Example #1
0
    def test_wkt_writer_precision(self):
        wkt_w = WKTWriter()
        self.assertIsNone(wkt_w.precision)
        self.assertEqual(
            wkt_w.write(Point(1.0 / 3, 2.0 / 3)),
            b"POINT (0.3333333333333333 0.6666666666666666)",
        )

        wkt_w.precision = 1
        self.assertEqual(wkt_w.precision, 1)
        self.assertEqual(wkt_w.write(Point(1.0 / 3, 2.0 / 3)),
                         b"POINT (0.3 0.7)")

        wkt_w.precision = 0
        self.assertEqual(wkt_w.precision, 0)
        self.assertEqual(wkt_w.write(Point(1.0 / 3, 2.0 / 3)), b"POINT (0 1)")

        wkt_w.precision = None
        self.assertIsNone(wkt_w.precision)
        self.assertEqual(
            wkt_w.write(Point(1.0 / 3, 2.0 / 3)),
            b"POINT (0.3333333333333333 0.6666666666666666)",
        )

        with self.assertRaisesMessage(
                AttributeError, "WKT output rounding precision must be "):
            wkt_w.precision = "potato"
def modeldiff_delete(r):
    obj, model = get_current_object_from_db(r)
    geom_field = model.Modeldiff.geom_field
    geom_precision = model.Modeldiff.geom_precision

    old_data = json.loads(r.old_data)
    ok_to_apply = True

    fields = list(old_data.keys())

    current = get_object_values(obj, model)

    for k in old_data:
        current_value = current.get(k)

        if k == geom_field:
            # early check to detect precision errors
            if not current_value == old_data[k]:
                # recreate the geometry and the wkt back again
                geom = GEOSGeometry(old_data[k])
                wkt_w = WKTWriter(precision=geom_precision)
                old_data[k] = wkt_w.write(geom)
        if not str(current_value) == str(old_data[k]):
            ok_to_apply = False

    r.fields = fields

    if ok_to_apply:
        obj._modeldiff_ignore = True
        obj.delete()
        r.applied = True
        r.save()
Example #3
0
    def _pre_delete(self, modeldiff_class, sender, **kwargs):
        instance = kwargs['instance']

        # see if we need to create a modeldiff to track the object deletion
        if hasattr(instance, '_modeldiff_ignore'):
            del instance._modeldiff_ignore
            return

        fields = sender.Modeldiff.fields

        diff = modeldiff_class()
        diff.applied = True
        diff.model_name = sender.Modeldiff.model_name
        diff.key = settings.MODELDIFF_KEY
        diff.username = self._get_username(instance)

        diff.model_id = instance.pk
        diff.action = 'delete'

        unique_field = getattr(sender.Modeldiff, 'unique_field', None)
        if unique_field:
            diff.unique_id = getattr(instance, unique_field)

        # get original object in database
        original = sender.objects.get(pk=instance.pk)

        # save old values
        old_values_temp = model_to_dict(original,
                                        fields=sender.Modeldiff.fields)
        old_values = {}

        for k in fields:
            old_value = old_values_temp[k]

            # Override DateField and DateTimeField
            if isinstance(old_value, datetime.datetime):
                old_value = old_value.strftime("%Y-%m-%d %H:%M:%S.%f%z")
            else:
                if isinstance(old_value, datetime.date):
                    old_value = old_value.strftime("%Y-%m-%d")

            old_values[k] = old_value

        if modeldiff_class == Geomodeldiff:
            geom_field = sender.Modeldiff.geom_field
            geom_precision = sender.Modeldiff.geom_precision
            wkt_w = WKTWriter(precision=geom_precision)
            # save geometry
            geom = getattr(instance, geom_field)
            diff.the_geom = geom
            if geom:
                old_values[geom_field] = wkt_w.write(geom).decode('utf8')
            else:
                old_values[geom_field] = None

        diff.old_data = json.dumps(old_values)
        diff.save()

        if hasattr(sender.Modeldiff, 'parent_field'):
            getattr(instance, sender.Modeldiff.parent_field).save()
Example #4
0
def load_kml(verbose=True):
    """ Recorre la carpeta/data/kml --> introduce en la BD los linestrings de los KML 
    https://medium.com/@kitcharoenpoolperm/geodjango-import-data-from-kml-file-de110dba1f60 """
    # Ruta al archivo que queremos introducir en la BD BikeLanes
    kml_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), 'data', 'kml',
                     'bidegorris.kml'), )
    # Reading Data by DataSource
    ds = DataSource(kml_file)
    # Writes the Well-Known Text representation of a Geometry.
    wkt_w = WKTWriter()
    # Iterating Over Layers
    for layer in ds:
        for feat in layer:
            if (feat.geom.geom_type.name.startswith('Line')):
                # Get the feature geometry.
                geom = feat.geom
                # get the feature property
                property = get_feat_property(feat)
                if (len(geom.coords) >= 2):
                    # Make a GEOSGeometry object
                    lstring = GEOSGeometry(wkt_w.write(geom.geos), srid=4326)
                    lstring.transform(3035)
                    dist = lstring.length
                    line = BikeLane.objects.create(
                        name=property['name'],
                        distance=dist,
                        lstring=lstring,
                        # ST_Buffer() --> Poligonizamos los bidegorris a una anchura de 10m
                        # https://www.usna.edu/Users/oceano/pguth/md_help/html/approx_equivalents.htm#:~:text=0.00001%C2%B0%20%3D%201.11%20m
                        poly=lstring.buffer(10, quadsegs=8))
                    logger.info(line)
Example #5
0
    def test02_wktwriter(self):
        # Creating a WKTWriter instance, testing its ptr property.
        wkt_w = WKTWriter()
        self.assertRaises(TypeError, wkt_w._set_ptr, WKTReader.ptr_type())

        ref = GEOSGeometry('POINT (5 23)')
        ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)'
        self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
Example #6
0
    def test02_wktwriter(self):
        # Creating a WKTWriter instance, testing its ptr property.
        wkt_w = WKTWriter()
        self.assertRaises(TypeError, wkt_w._set_ptr, WKTReader.ptr_type())

        ref = GEOSGeometry('POINT (5 23)')
        ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)'
        self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
Example #7
0
 def test_wktwriter_constructor_arguments(self):
     wkt_w = WKTWriter(dim=3, trim=True, precision=3)
     ref = GEOSGeometry('POINT (5.34562 23 1.5)')
     if geos_version_tuple() > (3, 10):
         ref_wkt = 'POINT Z (5.346 23 1.5)'
     else:
         ref_wkt = 'POINT Z (5.35 23 1.5)'
     self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
Example #8
0
 def geoElement(self):
     wkt = WKTWriter()
     if self.poly:
         return wkt.write(self.poly)
     elif self.point:
         return wkt.write(self.point)
     else:
         return None
Example #9
0
    def test02_wktwriter(self):
        # Creating a WKTWriter instance, testing its ptr property.
        wkt_w = WKTWriter()
        with self.assertRaises(TypeError):
            wkt_w.ptr = WKTReader.ptr_type()

        ref = GEOSGeometry("POINT (5 23)")
        ref_wkt = "POINT (5.0000000000000000 23.0000000000000000)"
        self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
Example #10
0
 def test_create_pois_receives_geometries(self):
     geom1 = b'POINT (-1.3630867 -5.9835847)'
     geom2 = b'POINT (-1.3630872 -5.9835842)'
     with patch.object(Command, 'create_poi') as mocked:
         self.cmd.handle(point_layer=self.filename, verbosity=0)
         call1 = mocked.call_args_list[0][0]
         call2 = mocked.call_args_list[1][0]
         self.assertEqual(WKTWriter(precision=7).write(call1[0]), geom1)
         self.assertEqual(WKTWriter(precision=7).write(call2[0]), geom2)
def get_object_values(obj, model):
    geom_field = model.Modeldiff.geom_field
    geom_precision = model.Modeldiff.geom_precision

    values = model_to_dict(obj)
    geom = getattr(obj, geom_field)
    if geom:
        wkt_w = WKTWriter(precision=geom_precision)
        values[geom_field] = wkt_w.write(geom)
    return values
Example #12
0
def _force_2d(geom):
    """ https://groups.google.com/d/msg/django-users/7c1NZ76UwRU/xEAir0dUCQAJ """

    wkt_w = WKTWriter()
    wkt_w.outdim = 2
    geom_3d = GEOSGeometry(geom.wkt)
    temp = wkt_w.write(geom_3d)
    geom_2d = GEOSGeometry(temp)

    if geom_2d and isinstance(geom_2d, Polygon) is True:
        geom_2d = MultiPolygon(geom_2d)
    return geom_2d
Example #13
0
    def pre_save(self, model_instance, add):

        if not getattr(model_instance, self.attname):

            try:
                wkt_writer = WKTWriter(precision=self.precision)
                value = GEOSGeometry(wkt_writer.write(getattr(model_instance, self.field_name).simplify(self.simplify, preserve_topology=True)))
                if not isinstance(value, MultiPolygon):
                    value = MultiPolygon(value)
                setattr(model_instance, self.attname, value)
                return value
            except:
                pass

        return super(CachedMultiPolygonField, self).pre_save(model_instance, add)
Example #14
0
 def test_regulatory_sensitive_area_shape(self):
     filename = os.path.join(os.path.dirname(__file__), 'data',
                             'species_regu.shp')
     call_command(
         'import',
         'geotrek.sensitivity.parsers.RegulatorySensitiveAreaShapeParser',
         filename,
         verbosity=0)
     self.assertEqual(SensitiveArea.objects.count(), 0)
     SportPracticeFactory(name="sport")
     call_command(
         'import',
         'geotrek.sensitivity.parsers.RegulatorySensitiveAreaShapeParser',
         filename,
         verbosity=0)
     area = SensitiveArea.objects.first()
     self.assertEqual(str(area.species), "Nom")
     self.assertTrue(area.species.period10)
     self.assertTrue(area.species.period11)
     self.assertTrue(area.species.period12)
     self.assertFalse(area.species.period08)
     self.assertEqual(area.species.radius, 23)
     self.assertEqual(area.species.url, "http://test.com")
     self.assertEqual(area.contact, "Contact")
     self.assertEqual(area.description, "Test UTF8 éêè")
     self.assertEqual(
         WKTWriter(precision=7).write(area.geom), b'POLYGON (('
         b'929315.3613369 6483309.4435054, 929200.3539448 6483204.0200627, '
         b'928404.8861499 6482494.8078118, 928194.0392645 6482082.6979903, '
         b'927925.6886830 6481210.5586006, 927676.5060003 6481287.2301953, '
         b'927772.3454936 6481498.0770807, 927887.3528857 6481900.6029529, '
         b'928184.4553151 6482600.2312545, 928625.3169846 6483520.2903908, '
         b'929162.0181475 6483664.0496309, 929315.3613369 6483309.4435054'
         b'))')
Example #15
0
 def test_cli(self):
     filename = os.path.join(os.path.dirname(__file__), 'data',
                             'species.shp')
     call_command(
         'import',
         'geotrek.sensitivity.parsers.SpeciesSensitiveAreaShapeParser',
         filename,
         verbosity=0)
     self.assertEqual(SensitiveArea.objects.count(), 0)
     species = SpeciesFactory(name="Aigle royal")
     call_command(
         'import',
         'geotrek.sensitivity.parsers.SpeciesSensitiveAreaShapeParser',
         filename,
         verbosity=0)
     area = SensitiveArea.objects.first()
     self.assertEqual(area.species, species)
     self.assertEqual(area.contact, "Contact")
     self.assertEqual(area.description, "Test UTF8 éêè")
     self.assertEqual(
         WKTWriter(precision=7).write(area.geom), b'POLYGON (('
         b'929315.3613369 6483309.4435054, 929200.3539448 6483204.0200627, '
         b'928404.8861499 6482494.8078118, 928194.0392645 6482082.6979903, '
         b'927925.6886830 6481210.5586006, 927676.5060003 6481287.2301953, '
         b'927772.3454936 6481498.0770807, 927887.3528857 6481900.6029529, '
         b'928184.4553151 6482600.2312545, 928625.3169846 6483520.2903908, '
         b'929162.0181475 6483664.0496309, 929315.3613369 6483309.4435054'
         b'))')
Example #16
0
 def test_good_data(self):
     filename = os.path.join(os.path.dirname(__file__), 'data', 'city.shp')
     call_command('import', 'geotrek.zoning.parsers.CityParser', filename, verbosity=0)
     city = City.objects.get()
     self.assertEqual(city.code, "99999")
     self.assertEqual(city.name, "Trifouilli-les-Oies")
     self.assertEqual(WKTWriter(precision=4).write(city.geom), WKT)
def modeldiff_update(r):
    obj, model = get_current_object_from_db(r)
    geom_field = model.Modeldiff.geom_field
    geom_precision = model.Modeldiff.geom_precision

    old_data = json.loads(r.old_data)
    ok_to_apply = True

    fields = list(old_data.keys())

    current = get_object_values(obj, model)

    for k in old_data:
        current_value = current.get(k)

        if k == geom_field:
            # early check to detect precision errors
            if not current_value == old_data[k]:
                # recreate the geometry and the wkt back again
                geom = GEOSGeometry(old_data[k])
                wkt_w = WKTWriter(precision=geom_precision)
                old_data[k] = wkt_w.write(geom)

        if not str(current_value) == str(old_data[k]):
            ok_to_apply = False

    r.fields = fields

    if ok_to_apply:
        fields = get_fields(r) or list(old_data.keys())
        new_data = json.loads(r.new_data)
        for k in set(fields) & set(new_data.keys()):
            field = model._meta.get_field(k)
            if isinstance(field, ForeignKey):
                if new_data[k]:
                    # TODO: support multiple to_fields
                    kwargs = {field.to_fields[0]: new_data[k]}
                    value = field.related_model.objects.get(**kwargs)
                else:
                    value = None
            else:
                value = new_data[k]
            setattr(obj, k, value)
        save_object(obj)
        r.applied = True
        r.save()
Example #18
0
 def _parse_columns(self, dataframe):
     '''
     parse the columns of the input dataframe to match the data type
     of the fields
     '''
     dataframe = dataframe.copy()
     error_occured = False
     for column in dataframe.columns:
         _meta = self.Meta.model._meta
         field_name = self.field_map.get(column, None)
         if field_name is None or isinstance(field_name, Reference):
             continue
         field = _meta.get_field(field_name)
         if (isinstance(field, PointField)
                 or isinstance(field, PolygonField)
                 or isinstance(field, MultiPolygonField)):
             self.wkt_w = WKTWriter(dim=2)
             dataframe['wkt'] = dataframe['wkt'].apply(self._parse_wkt)
             types = dataframe['wkt'].apply(type)
             str_idx = types == str
             error_idx = dataframe.index[str_idx]
             error_msg = _('Invalid geometry')
             self.error_mask.set_error(error_idx, 'wkt', error_msg)
             if len(error_idx) > 0:
                 error_occured = _('Invalid geometries')
         elif (isinstance(field, IntegerField)
               or isinstance(field, FloatField)
               or isinstance(field, DecimalField)
               or isinstance(field, BooleanField)):
             # set predefined nan-values to nan
             dataframe[column] = dataframe[column].replace(
                 self.nan_values, np.NaN)
             # parse the values (which are not nan)
             not_na = dataframe[column].notna()
             entries = dataframe[column].loc[not_na]
             if isinstance(field, IntegerField):
                 entries = entries.apply(self._parse_int)
                 error_msg = _('Integer expected: number without decimals')
             elif (isinstance(field, FloatField)
                   or isinstance(field, DecimalField)):
                 entries = entries.apply(self._parse_float)
                 error_msg = _('Float expected: number with or without '
                               'decimals; use either "," or "." as decimal-'
                               'seperators, no thousand-seperators allowed')
             elif isinstance(field, BooleanField):
                 entries = entries.apply(self._parse_bool)
                 error_msg = _('Boolean expected ("true" or "false")')
             # nan is used to determine parsing errors
             error_idx = entries[entries.isna()].index
             if len(error_idx) > 0:
                 error_occured = _('Number format errors')
             # set the error message in the error matrix at these positions
             self.error_mask.set_error(error_idx, column, error_msg)
             # overwrite values in dataframe with parsed ones
             dataframe.loc[not_na, column] = entries
     if error_occured:
         self.error_mask.add_message(error_occured)
     return dataframe
Example #19
0
    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)')
Example #20
0
    def to_representation(self, value):
        if isinstance(value, dict) or value is None:
            return value
        new_value = copy.copy(value)
        new_value = new_value.buffer(0.5)

        # Use Douglas-Peucker to simplify geom (one vertex 0.2m) for large polygons
        if new_value.num_coords > 1000:
            new_value = new_value.simplify(0.2, preserve_topology=False)
        new_value.transform(4326)

        wkt_w = WKTWriter()
        # number of decimals
        wkt_w.precision = 6

        if new_value.area > 0:
            return wkt_w.write(new_value).decode()
        return 'POLYGON EMPTY'
Example #21
0
    def test_wkt_writer_precision(self):
        wkt_w = WKTWriter()
        self.assertEqual(wkt_w.precision, None)
        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.assertEqual(wkt_w.precision, None)
        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'
Example #22
0
    def test_geo_creation_diff_exists(self):

        diff = Geomodeldiff.objects.all().order_by('-id')[:1][0]

        self.assertEqual(diff.action, 'add')
        self.assertEqual(diff.model_id, self.persongeo.id)
        self.assertEqual(diff.model_name, 'modeldiff.PersonGeoModel')
        self.assertEqual(diff.old_data, '')

        self.assertEqual(
            json.loads(diff.new_data), {
                'name': 'Foo',
                'surname': 'Doe',
                'birthdate': '2007-12-05',
                'updated_at': '2015-01-07 22:00:10.292032+0000',
                'the_geom': 'POINT (0.00000000 0.00000000)'
            })
        wkt_w = WKTWriter(precision=8)
        self.assertEqual(wkt_w.write(diff.the_geom),
                         b'POINT (0.00000000 0.00000000)')
Example #23
0
    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)')
Example #24
0
    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'
Example #25
0
 def test_create(self):
     filename = os.path.join(os.path.dirname(__file__), 'data', 'trek.shp')
     call_command('import',
                  'geotrek.trekking.parsers.TrekParser',
                  filename,
                  verbosity=0)
     trek = Trek.objects.all().last()
     self.assertEqual(trek.name, "Balade")
     self.assertEqual(trek.difficulty, self.difficulty)
     self.assertEqual(trek.route, self.route)
     self.assertQuerysetEqual(trek.themes.all(),
                              [repr(t) for t in self.themes],
                              ordered=False)
     self.assertEqual(WKTWriter(precision=4).write(trek.geom), WKT)
Example #26
0
def convert_geometry(config, geometry):
    """Converts the user requested geometry into the format supported by the ogcapi process services"""
    # This is configured for a single implementation to be more flexible would require parsing the process description,
    # and attempting to map the values to the correct schema type.
    area = config.get("area")
    config["inputs"]["geometry"] = {"format": area["type"]}
    if area["type"] == "wkt":
        config["inputs"]["geometry"]["input"] = WKTWriter().write(
            geometry).decode()
    if area["type"] == "geojson":
        config["inputs"]["geometry"]["input"] = {
            "type":
            "FeatureCollection",
            "features": [{
                "type": "Feature",
                "geometry": json.loads(geometry.geojson)
            }],
        }
    if area["type"] == "bbox":
        config["inputs"]["geometry"]["input"] = list(geometry.extent)
    return config
Example #27
0
    def save(self, *args, **kwargs):
        # see if we need to save the object (real = True)
        # or should generate a Modeldiff (real = False)
        ignore = kwargs.get('modeldiff_ignore', False)

        if ignore:
            # call original handler
            kwargs.pop('modeldiff_ignore')
            super(SaveGeomodeldiffMixin, self).save(*args, **kwargs)
            return

        fields = self.Modeldiff.fields
        geom_field = self.Modeldiff.geom_field
        geom_precision = self.Modeldiff.geom_precision

        diff = Geomodeldiff()
        diff.applied = True
        diff.model_name = self.Modeldiff.model_name
        diff.key = settings.MODELDIFF_KEY
        if hasattr(self, 'username'):
            diff.username = self.username
        else:
            try:
                diff.username = GlobalRequest().user.username
            except Exception:
                pass

        unique_field = getattr(self.Modeldiff, 'unique_field', None)
        if unique_field:
            diff.unique_id = getattr(self, unique_field)

        original = None
        if self.pk:
            # get original object in database
            try:
                original = self.__class__.objects.get(pk=self.pk)
            except Exception:
                pass
        wkt_w = WKTWriter(precision=geom_precision)
        if original:
            diff.model_id = self.pk
            diff.action = 'update'

            # compare original and current (self)
            old_values = {}
            new_values = {}
            old_values_temp = model_to_dict(original,
                                            fields=self.Modeldiff.fields)
            new_values_temp = model_to_dict(self, fields=self.Modeldiff.fields)

            for k in fields:
                old_value = old_values_temp[k]
                new_value = new_values_temp[k]

                # Override DateField and DateTimeField
                if isinstance(new_value, datetime.datetime):
                    new_value = new_value.strftime("%Y-%m-%d %H:%M:%S.%f%z")
                else:
                    if isinstance(new_value, datetime.date):
                        new_value = new_value.strftime("%Y-%m-%d")

                if isinstance(old_value, datetime.datetime):
                    old_value = old_value.strftime("%Y-%m-%d %H:%M:%S.%f%z")
                else:
                    if isinstance(old_value, datetime.date):
                        old_value = old_value.strftime("%Y-%m-%d")

                old_values[k] = old_value

                if old_value != new_value:
                    new_values[k] = new_value

            # save original geometry
            geom = getattr(original, geom_field)
            if geom:
                old_values[geom_field] = wkt_w.write(geom).decode('utf8')
            else:
                old_values[geom_field] = None

            # compare original and new geometry
            new_geom = getattr(self, geom_field)
            diff.the_geom = new_geom
            if new_geom:
                new_geom_value = wkt_w.write(new_geom).decode('utf8')
            else:
                new_geom_value = None

            if not new_geom_value == old_values[geom_field]:
                new_values[geom_field] = new_geom_value

            diff.old_data = json.dumps(old_values)
            diff.new_data = json.dumps(new_values)
            diff.save()
        else:
            diff.action = 'add'
            # save all new values
            new_values_temp = model_to_dict(self, fields=self.Modeldiff.fields)
            new_values = {}

            for k in fields:
                new_value = new_values_temp[k]
                # Override DateField and DateTimeField
                if isinstance(new_value, datetime.datetime):
                    new_value = new_value.strftime("%Y-%m-%d %H:%M:%S.%f%z")
                else:
                    if isinstance(new_value, datetime.date):
                        new_value = new_value.strftime("%Y-%m-%d")

                new_values[k] = new_value

            new_geom = getattr(self, geom_field)
            diff.the_geom = new_geom
            if new_geom:
                new_values[geom_field] = wkt_w.write(new_geom).decode('utf8')
            diff.new_data = json.dumps(new_values)
            diff.save()

        super(SaveGeomodeldiffMixin, self).save(*args, **kwargs)
        if diff.model_id is None and self.pk:
            diff.model_id = self.pk
            diff.save()

        if hasattr(self.Modeldiff, 'parent_field'):
            getattr(self, self.Modeldiff.parent_field).save()
Example #28
0
def _strip_z_values(features):
    for feature in features:
        writer = WKTWriter()
        writer.outdim = 2  # force features into 2 dimensions
        feature.multipolygon = GEOSGeometry(writer.write(feature.multipolygon))
    return features
Example #29
0
 def convert_3d_to_2d(self, shape_3d):
     wkt_w = WKTWriter()
     wkt_w.outdim = 2
     temp = wkt_w.write(shape_3d)
     return GEOSGeometry(temp)
Example #30
0
 def test_wktwriter_constructor_arguments(self):
     wkt_w = WKTWriter(dim=3, trim=True, precision=3)
     ref = GEOSGeometry('POINT (5.34562 23 1.5)')
     ref_wkt = 'POINT Z (5.35 23 1.5)'
     self.assertEqual(ref_wkt, wkt_w.write(ref).decode())
Example #31
0
    def delete_deprecated(self, *args, **kwargs):  # pragma: no cover
        real = kwargs.get('real', False)

        if real:
            # call original handler
            kwargs.pop('real')
            super(SaveGeomodeldiffMixin, self).delete(*args, **kwargs)
            return

        fields = self.Modeldiff.fields
        geom_field = self.Modeldiff.geom_field
        geom_precision = self.Modeldiff.geom_precision

        diff = Geomodeldiff()
        diff.model_name = self.Modeldiff.model_name
        if hasattr(self, 'username'):
            diff.username = self.username
        else:
            try:
                diff.username = GlobalRequest().user.username
            except Exception:
                pass

        if self.pk:
            diff.model_id = self.pk
            diff.action = 'delete'
            # get original object in database
            original = self.__class__.objects.get(pk=self.pk)

            # save old values
            old_values_temp = model_to_dict(original,
                                            fields=self.Modeldiff.fields)
            old_values = {}

            for k in fields:
                old_value = old_values_temp[k]

                # Override DateField and DateTimeField
                if isinstance(old_value, datetime.datetime):
                    old_value = old_value.strftime("%Y-%m-%d %H:%M:%S.%f%z")
                else:
                    if isinstance(old_value, datetime.date):
                        old_value = old_value.strftime("%Y-%m-%d")

                old_values[k] = old_value

            # save geometry
            geom = getattr(self, geom_field)
            diff.the_geom = geom
            wkt_w = WKTWriter(precision=geom_precision)
            if geom:
                old_values[geom_field] = wkt_w.write(geom).decode('utf8')
            else:
                old_values[geom_field] = None

            diff.old_data = json.dumps(old_values)
            diff.save()

        super(SaveGeomodeldiffMixin, self).delete(*args, **kwargs)

        if hasattr(self.Modeldiff, 'parent_field'):
            getattr(self, self.Modeldiff.parent_field).save()
Example #32
0
def getPath(request):
    data = request.get_full_path().split('?')[1]
    result = data.replace("%20", " ")

    namePair = result.split(" ")
    firstName = namePair[0]
    lastName = namePair[1]

    person = Vulnerable.objects.filter(first_name=firstName,
                                       last_name=lastName).first()
    wkt_w = WKTWriter()
    loc_activities = LostActivity.objects.prefetch_related(
        'location', 'person').filter(person=person,
                                     category="Location").order_by('time')

    j = 0
    # for the table summary. Group all similar location activities in order
    currlocation = None
    currentplace = None
    startDate = None
    processed = []

    journeys = [
        []
    ]  # list of lists of separate journey dicts to then add to ordered dict of features for template to draw
    feature_fences = []  # list of lists of locations to add
    for l in loc_activities:
        if not startDate:
            startDate = l.time.date()

        # current point
        pnt = Point(float(l.locLon), float(l.locLat), srid=3857)
        # see if activity in geofence but needs to be updated in database (new geofence created recently)
        if not l.location:
            fence_loc = Location.objects.filter(fence__contains=pnt)
            if fence_loc:
                l.location = fence_loc[0]
                l.update()

        prior = {}
        prior['name'] = None
        prior['act_type'] = None
        if len(journeys[j]) > 0:
            prior = journeys[j][-1]

        # if hit a known location add nearest boundary points too
        if l.location:

            # for the processed table groupings (append each place travelled to in order)
            if l.location != currlocation:
                processed.append({
                    "time": str(l.time),
                    "location": l.location,
                    "person": l.person,
                    "activity_type": str(l.activity_type)
                })
                currentplace = l
                currlocation = l.location

            # add the ENTRY boundary point then the location
            if str(l.location.name):  # if has name then at known geofence

                # went from location to location
                if (prior['act_type'] == "geo_fence" or prior['act_type']
                        == "exit place") and prior['name'] != l.location.name:
                    # use centroids as point to point reference
                    a = prior['feature'].lstrip('b')
                    prior['feature'] = a[1:-1]
                    last_cnt = GEOSGeometry(prior['feature']).centroid

                    wkt_feat = wkt_w.write(last_cnt)
                    a = str(wkt_feat)
                    b = a.lstrip('b')
                    wkt_feat = b[1:-1]
                    to_add = point_map_record(str(l.location.name), wkt_feat,
                                              last_cnt, l, "exit place")
                    journeys[j].append(to_add)
                    # start next journey
                    journeys.append([])
                    j += 1

                    # add entry point
                    curr_cnt = l.location.fence.centroid
                    wkt_feat = curr_cnt.wkt
                    to_add = point_map_record(str(l.location.name), wkt_feat,
                                              curr_cnt, l, "enter location")
                    journeys[j].append(to_add)

                # entered new location after a travel point
                # get entry point based on last recorded location
                elif prior['name'] and prior['name'] != l.location.name:
                    last_pnt = Point(float(prior['locLon']),
                                     float(prior['locLat']),
                                     srid=3857)
                    boundary = l.location.fence.boundary
                    opt_dist = boundary.project(last_pnt)
                    # get point on boundary at that distance
                    entry = boundary.interpolate(opt_dist)
                    wkt_feat = wkt_w.write(entry)
                    a = str(wkt_feat)
                    b = a.lstrip('b')
                    wkt_feat = b[1:-1]
                    to_add = point_map_record(str(l.location.name), wkt_feat,
                                              entry, l, "enter location")
                    journeys[j].append(to_add)

                # add current location even if stayed in same location
                wkt_fence = wkt_w.write(l.location.fence)
                to_add = geofence_record(l, wkt_fence, True)
                journeys[j].append(to_add)

        # just travel point
        else:
            # for the table count travel as no location
            currlocation = None
            currentplace = None

            # may need exit point from last location to this current point
            if prior['act_type'] == "geo_fence":
                a = prior['feature']
                b = a.lstrip('b')
                prior['feature'] = b[1:-1]
                boundary = GEOSGeometry(prior['feature']).boundary
                opt_dist = boundary.project(pnt)
                exitpnt = boundary.interpolate(opt_dist)
                wkt_feat = wkt_w.write(exitpnt)
                a = str(wkt_feat)
                b = a.lstrip('b')
                wkt_feat = b[1:-1]
                to_add = point_map_record(str(prior['name']), wkt_feat,
                                          exitpnt, l, "exit place")
                journeys[j].append(to_add)

                # start next journey after exit
                journeys.append([])
                j += 1

            wkt_feat = wkt_w.write(pnt)
            a = str(wkt_feat)
            b = a.lstrip('b')
            wkt_feat = b[1:-1]
            reg_point = point_map_record("journey: " + str(j), wkt_feat, pnt,
                                         l, "moving")
            journeys[j].append(reg_point)

    # get additional known locations details for this person or their friends' homes
    fences = list(Location.objects.filter(person=person))
    for f in fences:
        wkt_fence = wkt_w.write(f.fence)
        to_add = geofence_record(f, wkt_fence, False)
        feature_fences.append([to_add])

    return Response(journeys)