def test_geometryfield(self): "Testing the general GeometryField." Feature(name='Point', geom=Point(1, 1)).save() Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save() Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save() Feature(name='GeometryCollection', geom=GeometryCollection( Point(2, 2), LineString((0, 0), (2, 2)), Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save() f_1 = Feature.objects.get(name='Point') self.assertIsInstance(f_1.geom, Point) self.assertEqual((1.0, 1.0), f_1.geom.tuple) f_2 = Feature.objects.get(name='LineString') self.assertIsInstance(f_2.geom, LineString) self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple) f_3 = Feature.objects.get(name='Polygon') self.assertIsInstance(f_3.geom, Polygon) f_4 = Feature.objects.get(name='GeometryCollection') self.assertIsInstance(f_4.geom, GeometryCollection) self.assertEqual(f_3.geom, f_4.geom[2])
def _load_city_data(self): for name, pnt_data in city_data: City3D.objects.create( name=name, point=Point(*pnt_data, srid=4326), pointg=Point(*pnt_data, srid=4326), )
def test_geometry_value_annotation_different_srid(self): p = Point(1, 1, srid=32140) point = City.objects.annotate(p=Value(p, GeometryField( srid=4326))).first().p self.assertTrue( point.equals_exact(p.transform(4326, clone=True), 10**-5)) self.assertEqual(point.srid, 4326)
def test_olmap_OSM_rendering(self): delete_all_btn = """<a href="javascript:geodjango_point.clearFeatures()">Delete all Features</a>""" original_geoadmin = site._registry[City] params = original_geoadmin.get_map_widget( City._meta.get_field('point')).params result = original_geoadmin.get_map_widget( City._meta.get_field('point'))().render( 'point', Point(-79.460734, 40.18476), params) self.assertIn( """geodjango_point.layers.base = new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");""", result) self.assertIn(delete_all_btn, result) site.unregister(City) site.register(City, UnmodifiableAdmin) try: geoadmin = site._registry[City] params = geoadmin.get_map_widget( City._meta.get_field('point')).params result = geoadmin.get_map_widget( City._meta.get_field('point'))().render( 'point', Point(-79.460734, 40.18476), params) self.assertNotIn(delete_all_btn, result) finally: site.unregister(City) site.register(City, original_geoadmin.__class__)
def test_azimuth(self): # Returns the azimuth in radians. azimuth_expr = functions.Azimuth(Point(0, 0, srid=4326), Point(1, 1, srid=4326)) self.assertAlmostEqual(City.objects.annotate(azimuth=azimuth_expr).first().azimuth, math.pi / 4) # Returns None if the two points are coincident. azimuth_expr = functions.Azimuth(Point(0, 0, srid=4326), Point(0, 0, srid=4326)) self.assertIsNone(City.objects.annotate(azimuth=azimuth_expr).first().azimuth)
def test03_PointApi(self): 'Testing Point API' q = Point(4, 5, 3) for p in (Point(1, 2, 3), fromstr('POINT (1 2 3)')): p[0:2] = [4, 5] for f in geos_function_tests: self.assertEqual(f(q), f(p), 'Point ' + f.__name__)
def test_union_mixed_srid(self): """The result SRID depends on the order of parameters.""" geom = Point(61.42915, 55.15402, srid=4326) geom_3857 = geom.transform(3857, clone=True) tol = 0.001 for city in City.objects.annotate(union=functions.Union('point', geom_3857)): expected = city.point | geom self.assertTrue(city.union.equals_exact(expected, tol)) self.assertEqual(city.union.srid, 4326) for city in City.objects.annotate(union=functions.Union(geom_3857, 'point')): expected = geom_3857 | city.point.transform(3857, clone=True) self.assertTrue(expected.equals_exact(city.union, tol)) self.assertEqual(city.union.srid, 3857)
def test_distance_order_by(self): qs = SouthTexasCity.objects.annotate( distance=Distance('point', Point(3, 3, srid=32140))).order_by( 'distance').values_list( 'name', flat=True).filter(name__in=('San Antonio', 'Pearland')) self.assertSequenceEqual(qs, ['San Antonio', 'Pearland'])
def test_geometry_field_option(self): """ When a model has several geometry fields, the 'geometry_field' option can be used to specify the field to use as the 'geometry' key. """ MultiFields.objects.create(city=City.objects.first(), name='Name', point=Point(5, 23), poly=Polygon( LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))) geojson = serializers.serialize('geojson', MultiFields.objects.all()) geodata = json.loads(geojson) self.assertEqual(geodata['features'][0]['geometry']['type'], 'Point') geojson = serializers.serialize('geojson', MultiFields.objects.all(), geometry_field='poly') geodata = json.loads(geojson) self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon') # geometry_field is considered even if not in fields (#26138). geojson = serializers.serialize('geojson', MultiFields.objects.all(), geometry_field='poly', fields=('city', )) geodata = json.loads(geojson) self.assertEqual(geodata['features'][0]['geometry']['type'], 'Polygon')
def test_lookup_insert_transform(self): "Testing automatic transform for lookups and inserts." # San Antonio in 'WGS84' (SRID 4326) sa_4326 = 'POINT (-98.493183 29.424170)' wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84 # San Antonio in 'WGS 84 / Pseudo-Mercator' (SRID 3857) other_srid_pnt = wgs_pnt.transform(3857, clone=True) # Constructing & querying with a point from a different SRID. Oracle # `SDO_OVERLAPBDYINTERSECT` operates differently from # `ST_Intersects`, so contains is used instead. if oracle: tx = Country.objects.get(mpoly__contains=other_srid_pnt) else: tx = Country.objects.get(mpoly__intersects=other_srid_pnt) self.assertEqual('Texas', tx.name) # Creating San Antonio. Remember the Alamo. sa = City.objects.create(name='San Antonio', point=other_srid_pnt) # Now verifying that San Antonio was transformed correctly sa = City.objects.get(name='San Antonio') self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6) self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6) # If the GeometryField SRID is -1, then we shouldn't perform any # transformation if the SRID of the input geometry is different. m1 = MinusOneSRID(geom=Point(17, 23, srid=4326)) m1.save() self.assertEqual(-1, m1.geom.srid)
def test00_GEOSIndexException(self): 'Testing Geometry IndexError' p = Point(1, 2) for i in range(-2, 2): p._checkindex(i) with self.assertRaises(IndexError): p._checkindex(2) with self.assertRaises(IndexError): p._checkindex(-3)
def test_union(self): """Union with all combinations of geometries/geometry fields.""" geom = Point(-95.363151, 29.763374, srid=4326) union = City.objects.annotate(union=functions.Union('point', geom)).get(name='Dallas').union expected = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)', srid=4326) self.assertTrue(expected.equals(union)) union = City.objects.annotate(union=functions.Union(geom, 'point')).get(name='Dallas').union self.assertTrue(expected.equals(union)) union = City.objects.annotate(union=functions.Union('point', 'point')).get(name='Dallas').union expected = GEOSGeometry('POINT(-96.801611 32.782057)', srid=4326) self.assertTrue(expected.equals(union)) union = City.objects.annotate(union=functions.Union(geom, geom)).get(name='Dallas').union self.assertTrue(geom.equals(union))
def test_sym_difference(self): geom = Point(5, 23, srid=4326) qs = Country.objects.annotate(sym_difference=functions.SymDifference('mpoly', geom)) # Oracle does something screwy with the Texas geometry. if oracle: qs = qs.exclude(name='Texas') for country in qs: self.assertTrue(country.mpoly.sym_difference(geom).equals(country.sym_difference))
def geos(self, query): "Return a GEOS Point object for the given query." ll = self.lon_lat(query) if ll: from djmodels.contrib.gis.geos import Point return Point(ll, srid=4326) else: return None
def test_wkt_writer_trim(self): wkt_w = WKTWriter() self.assertFalse(wkt_w.trim) self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1.0000000000000000 1.0000000000000000)') wkt_w.trim = True self.assertTrue(wkt_w.trim) self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1 1)') self.assertEqual(wkt_w.write(Point(1.1, 1)), b'POINT (1.1 1)') self.assertEqual(wkt_w.write(Point(1. / 3, 1)), b'POINT (0.3333333333333333 1)') wkt_w.trim = False self.assertFalse(wkt_w.trim) self.assertEqual(wkt_w.write(Point(1, 1)), b'POINT (1.0000000000000000 1.0000000000000000)')
def test_difference_mixed_srid(self): """Testing with mixed SRID (Country has default 4326).""" geom = Point(556597.4, 2632018.6, srid=3857) # Spherical Mercator qs = Country.objects.annotate(difference=functions.Difference('mpoly', geom)) # Oracle does something screwy with the Texas geometry. if oracle: qs = qs.exclude(name='Texas') for c in qs: self.assertTrue(c.mpoly.difference(geom).equals(c.difference))
def test_olmap_WMS_rendering(self): geoadmin = admin.GeoModelAdmin(City, site) result = geoadmin.get_map_widget( City._meta.get_field('point'))().render( 'point', Point(-79.460734, 40.18476)) self.assertIn( """geodjango_point.layers.base = new OpenLayers.Layer.WMS("OpenLayers WMS", """ """"http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic', format: 'image/jpeg'});""", result)
def test_intersection(self): geom = Point(5, 23, srid=4326) qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom)) for c in qs: if spatialite or (mysql and not connection.features.supports_empty_geometry_collection) or oracle: # When the intersection is empty, some databases return None. expected = None else: expected = c.mpoly.intersection(geom) self.assertEqual(c.inter, expected)
def test_argument_validation(self): with self.assertRaisesMessage(ValueError, 'SRID is required for all geometries.'): City.objects.annotate(geo=functions.GeoFunc(Point(1, 1))) msg = 'GeoFunc function requires a GeometryField in position 1, got CharField.' with self.assertRaisesMessage(TypeError, msg): City.objects.annotate(geo=functions.GeoFunc('name')) msg = 'GeoFunc function requires a geometric argument in position 1.' with self.assertRaisesMessage(TypeError, msg): City.objects.annotate(union=functions.GeoFunc(1, 'point')).get(name='Dallas')
def _handle_empty_point(self, geom): from djmodels.contrib.gis.geos import Point if isinstance(geom, Point) and geom.empty: if self.srid: # PostGIS uses POINT(NaN NaN) for WKB representation of empty # points. Use it for EWKB as it's a PostGIS specific format. # https://trac.osgeo.org/postgis/ticket/3181 geom = Point(float('NaN'), float('NaN'), srid=geom.srid) else: raise ValueError('Empty point is not representable in WKB.') return geom
def test_multiple_annotation(self): multi_field = MultiFields.objects.create( point=Point(1, 1), city=City.objects.get(name='Houston'), poly=Polygon(((1, 1), (1, 2), (2, 2), (2, 1), (1, 1))), ) qs = City.objects.values('name').annotate(distance=Min( functions.Distance('multifields__point', multi_field.city.point)), ).annotate( count=Count('multifields')) self.assertTrue(qs.first())
def test01_PointMutations(self): 'Testing Point mutations' for p in (Point(1, 2, 3), fromstr('POINT (1 2 3)')): self.assertEqual(p._get_single_external(1), 2.0, 'Point _get_single_external') # _set_single p._set_single(0, 100) self.assertEqual(p.coords, (100.0, 2.0, 3.0), 'Point _set_single') # _set_list p._set_list(2, (50, 3141)) self.assertEqual(p.coords, (50.0, 3141.0), 'Point _set_list')
def test_wkt_writer_precision(self): wkt_w = WKTWriter() self.assertIsNone(wkt_w.precision) self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3333333333333333 0.6666666666666666)') wkt_w.precision = 1 self.assertEqual(wkt_w.precision, 1) self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3 0.7)') wkt_w.precision = 0 self.assertEqual(wkt_w.precision, 0) self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0 1)') wkt_w.precision = None self.assertIsNone(wkt_w.precision) self.assertEqual(wkt_w.write(Point(1. / 3, 2. / 3)), b'POINT (0.3333333333333333 0.6666666666666666)') with self.assertRaisesMessage( AttributeError, 'WKT output rounding precision must be '): wkt_w.precision = 'potato'
def test_null_geometries_excluded_in_lookups(self): """NULL features are excluded in spatial lookup functions.""" null = State.objects.create(name='NULL', poly=None) queries = [ ('equals', Point(1, 1)), ('disjoint', Point(1, 1)), ('touches', Point(1, 1)), ('crosses', LineString((0, 0), (1, 1), (5, 5))), ('within', Point(1, 1)), ('overlaps', LineString((0, 0), (1, 1), (5, 5))), ('contains', LineString((0, 0), (1, 1), (5, 5))), ('intersects', LineString((0, 0), (1, 1), (5, 5))), ('relate', (Point(1, 1), 'T*T***FF*')), ('same_as', Point(1, 1)), ('exact', Point(1, 1)), ('coveredby', Point(1, 1)), ('covers', Point(1, 1)), ] for lookup, geom in queries: with self.subTest(lookup=lookup): self.assertNotIn( null, State.objects.filter(**{'poly__%s' % lookup: geom}))
def test06_Collection(self): 'Testing Collection mutations' points = ( MultiPoint(*map(Point, ((3, 4), (-1, 2), (5, -4), (2, 8)))), fromstr('MULTIPOINT (3 4,-1 2,5 -4,2 8)'), ) for mp in points: self.assertEqual(mp._get_single_external(2), Point(5, -4), 'Collection _get_single_external') mp._set_list(3, map(Point, ((5, 5), (3, -2), (8, 1)))) self.assertEqual(mp.coords, ((5.0, 5.0), (3.0, -2.0), (8.0, 1.0)), 'Collection _set_list') lsa = MultiPoint(*map(Point, ((5, 5), (3, -2), (8, 1)))) for f in geos_function_tests: self.assertEqual(f(lsa), f(mp), 'MultiPoint ' + f.__name__)
def test_olwidget_has_changed(self): """ Changes are accurately noticed by OpenLayersWidget. """ geoadmin = site._registry[City] form = geoadmin.get_changelist_form(None)() has_changed = form.fields['point'].has_changed initial = Point(13.4197458572965953, 52.5194108501149799, srid=4326) data_same = "SRID=3857;POINT(1493879.2754093995 6894592.019687599)" data_almost_same = "SRID=3857;POINT(1493879.2754093990 6894592.019687590)" data_changed = "SRID=3857;POINT(1493884.0527237 6894593.8111804)" self.assertTrue(has_changed(None, data_changed)) self.assertTrue(has_changed(initial, "")) self.assertFalse(has_changed(None, "")) self.assertFalse(has_changed(initial, data_same)) self.assertFalse(has_changed(initial, data_almost_same)) self.assertTrue(has_changed(initial, data_changed))
def test_diff_intersection_union(self): geom = Point(5, 23, srid=4326) qs = Country.objects.all().annotate( difference=functions.Difference('mpoly', geom), sym_difference=functions.SymDifference('mpoly', geom), union=functions.Union('mpoly', geom), intersection=functions.Intersection('mpoly', geom), ) if oracle: # Should be able to execute the queries; however, they won't be the same # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or # SpatiaLite). return for c in qs: self.assertTrue(c.mpoly.difference(geom).equals(c.difference)) if not (spatialite or mysql): self.assertEqual(c.mpoly.intersection(geom), c.intersection) self.assertTrue(c.mpoly.sym_difference(geom).equals(c.sym_difference)) self.assertTrue(c.mpoly.union(geom).equals(c.union))
def test_empty_point_wkb(self): p = Point(srid=4326) wkb_w = WKBWriter() wkb_w.srid = False with self.assertRaisesMessage( ValueError, 'Empty point is not representable in WKB.'): wkb_w.write(p) with self.assertRaisesMessage( ValueError, 'Empty point is not representable in WKB.'): wkb_w.write_hex(p) wkb_w.srid = True for byteorder, hex in enumerate([ b'0020000001000010E67FF80000000000007FF8000000000000', b'0101000020E6100000000000000000F87F000000000000F87F', ]): wkb_w.byteorder = byteorder self.assertEqual(wkb_w.write_hex(p), hex) self.assertEqual(GEOSGeometry(wkb_w.write_hex(p)), p) self.assertEqual(wkb_w.write(p), memoryview(binascii.a2b_hex(hex))) self.assertEqual(GEOSGeometry(wkb_w.write(p)), p)
def test_update_from_other_field(self): p1 = Point(1, 1, srid=4326) p2 = Point(2, 2, srid=4326) obj = ManyPointModel.objects.create( point1=p1, point2=p2, point3=p2.transform(3857, clone=True), ) # Updating a point to a point of the same SRID. ManyPointModel.objects.filter(pk=obj.pk).update(point2=F('point1')) obj.refresh_from_db() self.assertEqual(obj.point2, p1) # Updating a point to a point with a different SRID. if connection.features.supports_transform: ManyPointModel.objects.filter(pk=obj.pk).update(point3=F('point1')) obj.refresh_from_db() self.assertTrue( obj.point3.equals_exact(p1.transform(3857, clone=True), 0.1))
def test_update_with_expression(self): city = City.objects.create(point=Point(1, 1, srid=4326)) City.objects.filter(pk=city.pk).update( point=functions.Translate('point', 1, 1)) city.refresh_from_db() self.assertEqual(city.point, Point(2, 2, srid=4326))