예제 #1
0
    def as_postgresql(self, compiler, connection):
        function = None
        geo_field = GeometryField(
            srid=self.srid)  # Fake field to get SRID info
        expr2 = self.source_expressions[1]
        geography = self.source_is_geography()
        if expr2.output_field.geography != geography:
            if isinstance(expr2, Value):
                expr2.output_field.geography = geography
            else:
                self.source_expressions[1] = Cast(
                    expr2,
                    GeometryField(srid=expr2.output_field.srid,
                                  geography=geography),
                )

        if not geography and geo_field.geodetic(connection):
            # Geometry fields with geodetic (lon/lat) coordinates need special distance functions
            if self.spheroid:
                # DistanceSpheroid is more accurate and resource intensive than DistanceSphere
                function = connection.ops.spatial_function_name(
                    'DistanceSpheroid')
                # Replace boolean param by the real spheroid of the base field
                self.source_expressions[2] = Value(
                    geo_field.spheroid(connection))
            else:
                function = connection.ops.spatial_function_name(
                    'DistanceSphere')
        return super().as_sql(compiler, connection, function=function)
예제 #2
0
 def as_postgresql(self, compiler, connection):
     function = None
     geo_field = GeometryField(srid=self.srid)  # Fake field to get SRID info
     if self.source_is_geography():
         self.source_expressions.append(Value(self.spheroid))
     elif geo_field.geodetic(connection):
         # Geometry fields with geodetic (lon/lat) coordinates need length_spheroid
         function = connection.ops.spatial_function_name('LengthSpheroid')
         self.source_expressions.append(Value(geo_field.spheroid(connection)))
     else:
         dim = min(f.dim for f in self.get_source_fields() if f)
         if dim > 2:
             function = connection.ops.length3d
     return super().as_sql(compiler, connection, function=function)
예제 #3
0
 def as_postgresql(self, compiler, connection):
     function = None
     geo_field = GeometryField(
         srid=self.srid)  # Fake field to get SRID info
     if self.source_is_geography():
         self.source_expressions.append(Value(self.spheroid))
     elif geo_field.geodetic(connection):
         # Geometry fields with geodetic (lon/lat) coordinates need length_spheroid
         function = connection.ops.spatial_function_name('LengthSpheroid')
         self.source_expressions.append(
             Value(geo_field.spheroid(connection)))
     else:
         dim = min(f.dim for f in self.get_source_fields() if f)
         if dim > 2:
             function = connection.ops.length3d
     return super().as_sql(compiler, connection, function=function)
예제 #4
0
    def as_postgresql(self, compiler, connection):
        function = None
        geo_field = GeometryField(srid=self.srid)  # Fake field to get SRID info
        expr2 = self.source_expressions[1]
        geography = self.source_is_geography()
        if expr2.output_field.geography != geography:
            if isinstance(expr2, Value):
                expr2.output_field.geography = geography
            else:
                self.source_expressions[1] = Cast(
                    expr2,
                    GeometryField(srid=expr2.output_field.srid, geography=geography),
                )

        if not geography and geo_field.geodetic(connection):
            # Geometry fields with geodetic (lon/lat) coordinates need special distance functions
            if self.spheroid:
                # DistanceSpheroid is more accurate and resource intensive than DistanceSphere
                function = connection.ops.spatial_function_name('DistanceSpheroid')
                # Replace boolean param by the real spheroid of the base field
                self.source_expressions[2] = Value(geo_field.spheroid(connection))
            else:
                function = connection.ops.spatial_function_name('DistanceSphere')
        return super().as_sql(compiler, connection, function=function)