def clean(self, value): if value in validators.EMPTY_VALUES: return None try: value = json.loads(value) geom = value.get('geom') if geom is None: raise ValueError("No geom found in JSON") geom = wkt_to_geom(geom) if geom is None: raise ValueError("Invalid WKT in JSON") geom.transform(settings.SRID) # We have the list of snapped paths, we use them to modify the # geometry vertices snaplist = value.get('snap', []) if geom.num_coords != len(snaplist): raise ValueError("Snap list length != %s (%s)" % (geom.num_coords, snaplist)) paths_pk = [(i, p) for (i, p) in enumerate(snaplist)] paths = [(i, Path.objects.get(pk=pk)) for (i, pk) in paths_pk if pk is not None] paths = dict(paths) coords = list(geom.coords) for i, vertex in enumerate(coords): if len(vertex) == 2: vertex = (vertex[0], vertex[1], 0.0) path = paths.get(i) if path: snap = path.snap(Point(*vertex, srid=geom.srid)) vertex = snap.coords coords[i] = vertex return LineString(*coords, srid=settings.SRID) except (TypeError, Path.DoesNotExist, ValueError) as e: logger.warning("User input error: %s" % e) raise ValidationError(self.error_messages['invalid_snap_line'])
def test_wkt_to_geom_fail(self): geom_wkt = "GeometryCollection2 (1090 1090)" with self.assertRaises(GEOSException): wkt_to_geom(geom_wkt)
def test_wkt_to_geom(self): geom_wkt = "POINT (650000 750000)" geom = wkt_to_geom(geom_wkt, srid_from=2154) self.assertEqual(geom.ewkt, "SRID=2154;%s" % geom_wkt)