Beispiel #1
0
 def handle(self, *args, **options):
     print("Calculando country codes")
     b = kings
     aas = AdministrativeArea.objects.filter(depth=1)
     for aa in aas:
         cc = next(v['country_code'] for k, v in kings.items()
                   if v['id'] == aa.osm_id)
         print(f' > {aa.osm_type} {aa.osm_id} {aa.name}')
         print('   - Lineas: ', end='')
         # Linea.objects.filter(envolvente__intersects=aa.geometry_simple).update(country_code=cc)
         print(Linea.objects \
             .annotate(intersection_area=Area(Intersection(F('envolvente'), aa.geometry_simple)) / Area(F('envolvente'))) \
             .filter(intersection_area__gt=A(sq_m=0.65)) \
             .update(country_code=cc))
         print('   - Recorrido: ', end='')
         print(Recorrido.objects \
             .annotate(intersection_len=Length(Intersection(F('ruta_simple'), aa.geometry_simple)) / Length(F('ruta_simple'))) \
             .filter(intersection_len__gt=D(m=0.65)) \
             .update(country_code=cc))
         print('   - Parada: ', end='')
         print(
             Parada.objects.filter(
                 latlng__intersects=aa.geometry_simple).update(
                     country_code=cc))
         print('   - Poi: ', end='')
         print(
             Poi.objects.filter(
                 latlng__intersects=aa.geometry_simple).update(
                     country_code=cc))
         print('   - AdministrativeArea: ', end='')
         print(AdministrativeArea.objects \
             .annotate(intersection_area=Area(Intersection(F('geometry_simple'), aa.geometry_simple)) / Area(F('geometry_simple'))) \
             .filter(intersection_area__gt=A(sq_m=0.65)) \
             .update(country_code=cc))
         print(' > DONE')
Beispiel #2
0
    def test_job_region_intersection(self,):
        job = Job.objects.all()[0]
        # use the_geog
        regions = Region.objects.filter(the_geog__intersects=job.the_geog).annotate(
            intersection=Area(Intersection('the_geog', job.the_geog))).order_by('-intersection')
        self.assertEquals(2, len(regions))
        asia = regions[0]
        africa = regions[1]
        self.assertIsNotNone(asia)
        self.assertIsNotNone(africa)
        self.assertEquals('Central Asia/Middle East', asia.name)
        self.assertEquals('Africa', africa.name)
        self.assertTrue(asia.intersection > africa.intersection)

        # use the_geom
        regions = Region.objects.filter(the_geom__intersects=job.the_geom).intersection(job.the_geom,
                                                                                        field_name='the_geom').order_by(
            '-intersection')
        # logger.debug('Geometry lookup took: %s' % geom_time)
        self.assertEquals(2, len(regions))
        asia = regions[0]
        africa = regions[1]
        self.assertIsNotNone(asia)
        self.assertIsNotNone(africa)
        self.assertEquals('Central Asia/Middle East', asia.name)
        self.assertEquals('Africa', africa.name)
        self.assertTrue(asia.intersection.area > africa.intersection.area)
Beispiel #3
0
def get_all_layers(request):
	user_id = request.user.id
	queryset = adrian.objects.annotate(area=Area('geom')).filter(user_id=user_id).order_by('-area')
	if not queryset:
		return HttpResponse(status=204)
	geojson = serialize('geojson', queryset)
	return HttpResponse(geojson, content_type='json')
Beispiel #4
0
    def _get_from_pricing_layer_price(cls, **kwargs):
        """
        The area is expected to be in hectares
        As the price may vary from one polygon to
        the other, it has to be taken in the
        pricing layer
        """
        polygon = kwargs.get('polygon')
        pricing_instance = kwargs.get('pricing_instance')
        pricing_geometry_instance = pricing_instance.pricinggeometry_set
        if pricing_geometry_instance.count() == 0:
            LOGGER.info('%s HAS NO GEOMETRIES LINKED TO IT',
                        pricing_instance.name)
            send_geoshop_email(
                _('Geoshop - Error, pricing has no geometries linked to it'),
                template_name='email_admin',
                template_data={
                    'messages': [
                        _('The pricing "{}" is defined but no geometries were found for it.'
                          ).format(pricing_instance.name)
                    ]
                })
            return cls._get_manual_price(**kwargs)
        total = pricing_geometry_instance.filter(
            pricing=pricing_instance.id).filter(
                geom__intersects=polygon).aggregate(sum=ExpressionWrapper(
                    Sum((Area(Intersection('geom', polygon)) / 10000) *
                        F('unit_price')),
                    output_field=MoneyField()))

        return Money(total['sum'], pricing_instance.unit_price_currency)
Beispiel #5
0
def get_regions_for_zone(zone):
    """Returns the best region for the zone based on amount of overlap with the zone's bounding box.

    If the zone only falls within one region, that region is returned.

    Otherwise, this calculates the amount of overlap between the zone's bounding box and the region
    and returns the one with the highest amount of overlap, as an approximation of the region that
    contains most or all of the zone polygon.

    Parameters
    ----------
    extent : SeedZone instance

    Returns
    -------
    Region instance
    """

    extent = Polygon.from_bbox(zone.polygon.extent)
    regions = Region.objects.filter(polygons__intersects=extent)

    if len(regions) == 1:
        return list(regions)

    # calculate amount of overlap and return one with highest overlap with extent
    return list(
        regions.annotate(overlap=Area(Intersection(
            "polygons", extent))).order_by("-overlap"))
Beispiel #6
0
    def load(self, path):
        self.stdout.write("\nCountry\n")
        self.load_by_path(path, 'VG250_STA.shp', 'country', 0)

        self.stdout.write("\nState\n")
        self.load_by_path(path, 'VG250_LAN.shp', 'state', 1)

        self.stdout.write("\nAdministrative District\n")
        self.load_by_path(path, 'VG250_RBZ.shp', 'admin_district', 2)

        self.stdout.write("\nDistrict\n")
        self.load_by_path(path, 'VG250_KRS.shp', 'district', 3)

        self.stdout.write("\nAdmin Cooperation\n")
        self.load_by_path(path, 'VG250_VWG.shp', 'admin_cooperation', 4)

        self.stdout.write("\nMunicipalities\n")
        self.load_by_path(path, 'VG250_GEM.shp', 'municipality', 5)

        self.stdout.write("\nSet Gov seats\n")
        self.set_gov_seats(path, 'VG250_PK.shp')

        self.stdout.write("Create Hierarchy\n")
        self.create_hierarchy()

        self.stdout.write("Calculate Area\n")
        GeoRegion.objects.all().update(area=Area('geom'))
Beispiel #7
0
 def test_area(self):
     # Reference queries:
     # SELECT ST_Area(poly) FROM distapp_southtexaszipcode;
     area_sq_m = [5437908.90234375, 10183031.4389648, 11254471.0073242, 9881708.91772461]
     # Tolerance has to be lower for Oracle
     tol = 2
     for i, z in enumerate(SouthTexasZipcode.objects.annotate(area=Area('poly')).order_by('name')):
         self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol)
 def test_geography_area(self):
     """
     Testing that Area calculations work on geography columns.
     """
     # SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
     ref_area = 5439100.13587 if oracle else 5439084.70637573
     tol = 5
     z = Zipcode.objects.annotate(area=Area('poly')).get(code='77002')
     self.assertAlmostEqual(z.area.sq_m, ref_area, tol)
Beispiel #9
0
 def test_geography_area(self):
     """
     Testing that Area calculations work on geography columns.
     """
     # SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002';
     z = Zipcode.objects.annotate(area=Area('poly')).get(code='77002')
     # Round to the nearest thousand as possible values (depending on
     # the database and geolib) include 5439084, 5439100, 5439101.
     rounded_value = z.area.sq_m
     rounded_value -= z.area.sq_m % 1000
     self.assertEqual(rounded_value, 5439000)
Beispiel #10
0
 def test_measurement_null_fields(self):
     """
     Test the measurement functions on fields with NULL values.
     """
     # Creating SouthTexasZipcode w/NULL value.
     SouthTexasZipcode.objects.create(name='78212')
     # Performing distance/area queries against the NULL PolygonField,
     # and ensuring the result of the operations is None.
     htown = SouthTexasCity.objects.get(name='Downtown Houston')
     z = SouthTexasZipcode.objects.annotate(
         distance=Distance('poly', htown.point),
         area=Area('poly')).get(name='78212')
     self.assertIsNone(z.distance)
     self.assertIsNone(z.area)
Beispiel #11
0
 def test_job_region_intersection(self, ):
     job = Job.objects.all()[0]
     # use the_geog
     regions = Region.objects.filter(
         the_geog__intersects=job.the_geog).annotate(
             intersection=Area(Intersection(
                 'the_geog', job.the_geog))).order_by('-intersection')
     self.assertEqual(2, len(regions))
     asia = regions[0]
     africa = regions[1]
     self.assertIsNotNone(asia)
     self.assertIsNotNone(africa)
     self.assertEqual('Central Asia/Middle East', asia.name)
     self.assertEqual('Africa', africa.name)
     self.assertTrue(asia.intersection > africa.intersection)
Beispiel #12
0
    def load(self, path):
        self.valid_date = localize_date(datetime(2021, 1, 1, 0, 0, 0))

        self.georegions = GeoRegion.objects.filter(kind__in=[x[2] for x in self.layers])

        for name, filename, kind, level in self.layers:
            self.stdout.write("\n%s\n" % name)
            self.load_by_path(path, filename, kind, level)

        GeoRegion.fix_tree()
        self.stdout.write("\nSet Gov seats\n")
        self.set_gov_seats(path, "VG250_PK.shp")

        self.stdout.write("Calculate Area\n")
        GeoRegion.objects.all().update(area=Area("geom"))
Beispiel #13
0
def run():
    geojson = os.path.abspath(os.path.join(os.path.dirname(ui.__file__), '..' , 'data', 'Swiss-cantons.geojson'))
    with open(geojson, encoding='utf-8') as f:
        cantons = json.load(f)
    for canton in cantons['features']:
        properties = canton['properties']
        canton_model = Canton()
        canton_model.id = properties['real_id']
        canton_model.name = properties['name']
        canton_model.population = properties['population']
        canton_model.cars= properties['cars']
        canton_model.mpoly = GEOSGeometry(json.dumps(canton['geometry']))
        canton_model.country = Country.objects.get(id=properties['country_id'])
        
        canton_model.save()
        canton_model = Canton.objects.annotate(area_=Area('mpoly')).get(id=canton_model.id)
        canton_model.area = canton_model.area_.sq_m
        canton_model.save()
Beispiel #14
0
def polygonStats(request):
    param = request.GET.get('geojson', None)
    if not param:
        raise Http404
    response = {}
    parsed_geojson = json.loads(param)
    geometry = GEOSGeometry(json.dumps(parsed_geojson['geometry']))
    country = models.Country.objects \
        .annotate(geom=Cast('mpoly', GeometryField())) \
        .filter(geom__contains=geometry) \
        .first()
    if country:
        metrics = models.Tile.objects \
            .annotate(geom=Cast('mpoly', GeometryField())) \
            .filter(geom__within=geometry) \
            .aggregate(Avg('tree_density'), Avg('tree_sparsity'), Sum(Area('mpoly')))
        tree_density = 0
        tree_sparsity = 0
        weights = [
            160,  # Tree coverage
            240,  # Tree sparsity
            2  # Relative area
        ]
        if metrics[
                'tree_density__avg']:  # Check if result returned, a.k.a has tiles
            tree_density = metrics['tree_density__avg']
            tree_sparsity = metrics['tree_sparsity__avg']
            rel_area = metrics['Area__sum'].sq_m / country.area
            score = np.dot(weights, [
                tree_density,
                functions.sparsity_to_representable(tree_sparsity), rel_area
            ])
            response['tree_density'] = tree_density
            response['tree_sparsity'] = tree_sparsity
            response['rel_area'] = rel_area
            response['score'] = score
    return JsonResponse(response)
Beispiel #15
0
def run(verbose=True):
    country_shape = os.path.abspath(
        os.path.join(os.path.dirname(ui.__file__), '..', 'data',
                     'Switzerland.geojson'))
    ds = DataSource(country_shape)
    lyr = ds[0]
    feat = lyr[0]
    layer_mapping = {
        'name': 'name:en',
        'id': 'real_id',
        'population': 'population',
        'mpoly': 'POLYGON'
    }
    layer_mapping = LayerMapping(Country,
                                 country_shape,
                                 layer_mapping,
                                 transform=False,
                                 encoding='iso-8859-1')
    layer_mapping.save(strict=True, verbose=verbose)

    country = Country.objects.annotate(area_=Area('mpoly')).get(id=51701)
    country.cars = feat.get('cars') / country.population
    country.area = country.area_.sq_m
    country.save()
Beispiel #16
0
 def test_geodetic_area_raises_if_not_supported(self):
     with self.assertRaisesMessage(
             NotSupportedError,
             'Area on geodetic coordinate systems not supported.'):
         Zipcode.objects.annotate(area=Area('poly')).get(code='77002')
Beispiel #17
0
def ver_linea(request, osm_type=None, osm_id=None, slug=None, country_code=None):
    """
        osm_type =
            - 'c': cualbondi recorrido, usar id de la tabla directamente
            - 'r': relation de osm, usar osm_id con el campo osm_id
    """
    # TODO: redirect id c123 a r123 si viene con osm_type=c y existe el osm_id
    linea_q = Linea.objects.only('nombre', 'slug', 'img_cuadrada', 'info_empresa', 'info_terminal', 'img_panorama', 'envolvente')
    linea = None
    if osm_type == 'c':
        linea = get_object_or_404(linea_q, id=osm_id)
    elif osm_type == 'r':
        linea = get_object_or_404(linea_q, osm_id=osm_id)

    linea__envolvente = linea.envolvente.simplify(0.001, True)

    recorridos = natural_sort_qs(linea.recorridos.all().defer('ruta'), 'slug')

    # aa = AdministrativeArea.objects \
    #     .filter(geometry_simple__intersects=linea.envolvente) \
    #     .annotate(inter_area=DBArea(Intersection(F('geometry_simple'), linea.envolvente))) \
    #     .filter(inter_area__gt=Area(sq_m=linea.envolvente.area * 0.8)) \
    #     .annotate(area=DBArea(F('geometry_simple'))) \
    #     .order_by('area')

    # aa = AdministrativeArea.objects \
    #     .filter(geometry_simple__intersects=linea.envolvente) \
    #     .annotate(symdiff_area=Area(SymDifference(F('geometry_simple'), linea.envolvente)) / Area(Union(F('geometry_simple'), linea.envolvente))) \
    #     .order_by('symdiff_area')

    aa = AdministrativeArea.objects \
        .filter(geometry_simple__intersects=linea__envolvente) \
        .annotate(symdiff_area=Area(SymDifference(F('geometry_simple'), linea__envolvente)) / (Area(F('geometry_simple')) + Area(linea__envolvente))) \
        .annotate(intersection_area=Area(Intersection(F('geometry_simple'), linea__envolvente)) / Area(linea__envolvente)) \
        .filter(intersection_area__gt=A(sq_m=0.8)) \
        .order_by('symdiff_area')

    # for a in aa:
    #     print(f'{a.symdiff_area, a.intersection_area, a.name}')

    # aa = AdministrativeArea.objects \
    #     .filter(geometry_simple__intersects=linea.envolvente) \
    #     .annotate(symdiff_area=Area(SymDifference(F('geometry_simple'), linea.envolvente))) \
    #     .order_by('symdiff_area')

    if aa:
        aa = aa[0]
        aaancestors = aa.get_ancestors().reverse()
    else:
        aa = None
        aaancestors = None

    # linea found, check if url is ok
    correct_url = linea.get_absolute_url()
    if correct_url not in request.build_absolute_uri():
        return HttpResponsePermanentRedirect(add_lang_qs(correct_url, request))

    # Zonas por las que pasa el recorrido
    aas = AdministrativeArea.objects \
        .filter(geometry_simple__intersects=linea__envolvente, depth__gt=3) \
        .order_by('depth', 'name')

    return render(
        request,
        "core/ver_linea.html",
        {
            'obj': linea,
            'recorridos': recorridos,
            'adminarea': aa,
            'adminareaancestors': aaancestors,
            'adminareas': aas,
        }
    )
Beispiel #18
0
 def get_queryset(self):
     return super().get_queryset().annotate(_area=Area('geometry'))
Beispiel #19
0
 def get_queryset(self):
     return super().get_queryset().annotate(_area=Area('geometry'), geom=Cast('geometry', output_field=models.GeometryField()), transformed=Transform('geom', 31370))
Beispiel #20
0
 def _get_from_pricing_layer_price(**kwargs):
     polygon = kwargs.get('polygon')
     unit_price = kwargs.get('unit_price')
     area = Area(polygon)
     return 'TODO_FROM_PRICING_LAYER'
Beispiel #21
0
 def get_queryset(self):
     wpp_area = WPP.objects.annotate(area=Area("mpoly")).order_by("area")
     return wpp_area
Beispiel #22
0
class DriverViewSet(ApiMixin, ModelViewSet):
    queryset = Driver.objects.annotate(
        area=Area('home_area')).order_by('-area')
    serializer_class = DriverReadSerializer
    serializers = {'create': DriverWriteSerializer}
Beispiel #23
0
def calculate_area_field(apps, schema_editor):
    SpatialUnit = apps.get_model('spatial', 'SpatialUnit')
    SpatialUnit.objects.exclude(geometry=None).extra(
        where=["geometrytype(geometry) LIKE 'POLYGON'"]).update(
            area=Area(Transform('geometry', 3857)))
    def handle(self, output_directory, zoneset, variables, periods, seed,
               *args, **kwargs):
        output_directory = output_directory[0]

        if zoneset is None or zoneset.strip() == "":
            sources = ZoneSource.objects.all().order_by("name")
            if len(sources) == 0:
                raise CommandError("No zonesets available to analyze")

        else:
            sources = ZoneSource.objects.filter(
                name__in=zoneset.split(",")).order_by("name")
            if len(sources) == 0:
                raise CommandError(
                    "No zonesets available to analyze that match --zones values"
                )

        if variables is None:
            variables = VARIABLES

        else:
            variables = set(variables.split(","))
            missing = variables.difference(VARIABLES)
            if missing:
                raise CommandError(
                    "These variables are not available: {}".format(
                        ",".join(missing)))

        if periods is None:
            periods = PERIODS

        else:
            periods = set(periods.split(","))
            missing = periods.difference(PERIODS)
            if missing:
                raise CommandError(
                    "These periods are not available: {}".format(
                        ",".join(missing)))

        ### Initialize random seed
        if seed is None:
            seed = int(time.time())
            print("Using random seed: {}".format(seed))

        numpy.random.seed(seed)

        ### Create output directories
        if not os.path.exists(output_directory):
            os.makedirs(output_directory)

        for period in periods:
            print("----------------------\nProcessing period {}\n".format(
                period))

            period_dir = os.path.join(output_directory, period)

            for variable in variables:
                sample_dir = os.path.join(period_dir,
                                          "{}_samples".format(variable))
                if not os.path.exists(sample_dir):
                    os.makedirs(sample_dir)

            with StatsWriters(period_dir, variables) as writer:
                for source in sources:
                    zones = source.seedzone_set.annotate(
                        area_meters=Area("polygon")).all().order_by("zone_id")

                    with ZoneConfig(source.name) as config, ElevationDataset(
                    ) as elevation_ds, ClimateDatasets(
                            period=period, variables=variables) as climate:
                        for zone in Bar(
                                "Processing {} zones".format(source.name),
                                max=source.seedzone_set.count(),
                        ).iter(zones):

                            # calculate area of zone polygon in acres
                            poly_acres = round(
                                zone.area_meters.sq_m * 0.000247105, 1)
                            zone_xmin, zone_ymin, zone_xmax, zone_ymax = zone.polygon.extent
                            zone_ctr_x = round(
                                ((zone_xmax - zone_xmin) / 2) + zone_xmin, 5)
                            zone_ctr_y = round(
                                ((zone_ymax - zone_ymin) / 2) + zone_ymin, 5)

                            region = get_regions_for_zone(zone)
                            elevation_ds.load_region(region.name)
                            climate.load_region(region.name)

                            window, coords = elevation_ds.get_read_window(
                                zone.polygon.extent)
                            transform = coords.affine

                            elevation = elevation_ds.data[window]

                            # calculate pixel area based on UTM centered on window
                            pixel_area = round(
                                calculate_pixel_area(
                                    transform, elevation.shape[1],
                                    elevation.shape[0]) * 0.000247105,
                                1,
                            )

                            zone_mask = rasterize(
                                (json.loads(zone.polygon.geojson), ),
                                out_shape=elevation.shape,
                                transform=transform,
                                fill=1,  # mask is True OUTSIDE the zone
                                default_value=0,
                                dtype=numpy.dtype("uint8"),
                            ).astype("bool")

                            # count rasterized pixels
                            raster_pixels = (zone_mask == 0).sum()

                            nodata_mask = elevation == elevation_ds.nodata_value
                            mask = nodata_mask | zone_mask

                            # extract all data not masked out as nodata or outside zone
                            # convert to feet
                            elevation = (elevation[~mask] /
                                         0.3048).round().astype("int")

                            # if there are no pixels in the mask, skip this zone
                            if elevation.size == 0:
                                continue

                            min_elevation = math.floor(numpy.nanmin(elevation))
                            max_elevation = math.ceil(numpy.nanmax(elevation))

                            bands = list(
                                config.get_elevation_bands(
                                    zone, min_elevation, max_elevation))
                            bands = generate_missing_bands(
                                bands, min_elevation, max_elevation)

                            if not bands:
                                # min / max elevation outside defined bands
                                raise ValueError(
                                    "Elevation range {} - {} ft outside defined bands\n"
                                    .format(min_elevation, max_elevation))

                            ### Extract data for each variable within each band
                            for variable, ds in climate.items():
                                # extract data with same shape as elevation above
                                data = ds.data[window][~mask]

                                # count the non-masked data pixels
                                # variables may be masked even if elevation is valid
                                zone_unit_pixels = data[
                                    data != ds.nodata_value].size

                                for band in bands:
                                    low, high = band[:2]
                                    band_mask = (elevation >= low) & (elevation
                                                                      <= high)

                                    if not numpy.any(band_mask):
                                        continue

                                    # extract actual elevation range within the mask as integer feet
                                    band_elevation = elevation[band_mask]
                                    band_range = [
                                        math.floor(
                                            numpy.nanmin(band_elevation)),
                                        math.ceil(
                                            numpy.nanmax(band_elevation)),
                                    ]

                                    # extract data within elevation range
                                    band_data = data[band_mask]

                                    # then apply variable's nodata mask
                                    band_data = band_data[
                                        band_data != ds.nodata_value]

                                    if not band_data.size:
                                        continue

                                    writer.write_row(
                                        variable,
                                        zone.zone_uid,
                                        band,
                                        band_range,
                                        band_data,
                                        period=period,
                                        zone_set=zone.source,
                                        species=zone.species.upper()
                                        if zone.species != "generic" else
                                        zone.species,
                                        zone_unit=zone.zone_id,
                                        zone_unit_poly_acres=poly_acres,
                                        zone_unit_raster_pixels=raster_pixels,
                                        zone_unit_raster_acres=raster_pixels *
                                        pixel_area,
                                        zone_unit_pixels=zone_unit_pixels,
                                        zone_unit_acres=zone_unit_pixels *
                                        pixel_area,
                                        zone_unit_low=min_elevation,
                                        zone_unit_high=max_elevation,
                                        zone_pixels=band_data.size,
                                        zone_acres=band_data.size * pixel_area,
                                        zone_unit_ctr_x=zone_ctr_x,
                                        zone_unit_ctr_y=zone_ctr_y,
                                        zone_unit_xmin=round(zone_xmin, 5),
                                        zone_unit_ymin=round(zone_ymin, 5),
                                        zone_unit_xmax=round(zone_xmax, 5),
                                        zone_unit_ymax=round(zone_ymax, 5),
                                    )

                                    self._write_sample(period_dir, variable,
                                                       zone.zone_uid,
                                                       zone.zone_id, band_data,
                                                       *band_range)
Beispiel #25
0
def ver_recorrido(request, osm_type=None, osm_id=None, slug=None, country_code=None):
    """
        osm_type =
            - 'c': cualbondi recorrido, usar id de la tabla directamente
            - 'r': relation de osm, usar osm_id con el campo osm_id
    """
    recorrido_q = Recorrido.objects \
        .only('nombre', 'slug', 'inicio', 'fin', 'img_cuadrada', 'img_panorama', 'ruta', 'linea', 'osm_id') \
        .select_related('linea')
    recorrido = None
    if osm_type == 'c':
        recorrido = get_object_or_404(recorrido_q, id=osm_id)
    elif osm_type == 'w':
        # there can be multiple with the same id, so we filter using the most approximate slug
        recorridos = Recorrido.objects.filter(osm_id=osm_id).annotate(similarity=TrigramSimilarity('slug', slug or '')).order_by('-similarity')
        if recorridos:
            recorrido = recorridos[0]
        else:
            raise Http404


    recorrido_simplified = recorrido.ruta.simplify(0.00005)
    recorrido_buffer = recorrido_simplified.buffer(0.0001)

    # aa = AdministrativeArea.objects \
    #     .filter(geometry_simple__intersects=recorrido_simplified) \
    #     .annotate(symdiff_area=Area(SymDifference(F('geometry_simple'), recorrido_simplified)) / (Area(F('geometry_simple')) + Area(recorrido_simplified))) \
    #     .order_by('symdiff_area')

    aa = AdministrativeArea.objects \
        .filter(geometry_simple__intersects=recorrido_buffer) \
        .annotate(symdiff_area=Area(SymDifference(F('geometry_simple'), recorrido_buffer)) / (Area(F('geometry_simple')) + Area(recorrido_buffer))) \
        .annotate(intersection_area=Area(Intersection(F('geometry_simple'), recorrido_buffer)) / Area(recorrido_buffer)) \
        .filter(intersection_area__gt=A(sq_m=0.8)) \
        .order_by('symdiff_area')

    if aa:
        aa = aa[0]
        aaancestors = aa.get_ancestors().reverse()
    else:
        aa = None
        aaancestors = None

    # recorrido found, check if url is ok
    correct_url = recorrido.get_absolute_url()
    if correct_url not in request.build_absolute_uri():
        return HttpResponsePermanentRedirect(add_lang_qs(correct_url, request))

    # Calles por las que pasa el recorrido
    """
    # solucion 1
    # toma todas las calles cercanas al recorrido
    # simple pero no funciona bien, genera "falsos positivos", trae calles perpendiculares al recorrido
    # igual es lento: 13 seg
    calles_fin = Calle.objects.filter(way__distance_lte=(recorrido.ruta, D(m=20)))

    # alternativa con dwithin
    # igual es lento, pero 10 veces mejor que antes: 1.4 seg
    calles_fin = Calle.objects.filter(way__dwithin=(recorrido.ruta, D(m=20)))
    """
    """
    # solucion 2
    # toma las calles que estan cercanas y se repiten cada par de puntos
    # hace 1 query lenta por cada punto: funciona bien, pero un poco lento!
    # 0.003 seg x cant_puntos
    calles_ant = None
    calles_fin = []
    for p in recorrido.ruta.coords:
        calles = Calle.objects.filter(way__dwithin=(Point(p), D(m=50)))
        if calles_ant is not None:
            for c in calles_ant:
                if len(calles_fin) > 0:
                    if c.nom != calles_fin[-1].nom and c in calles:
                        calles_fin.append(c)
                else:
                    calles_fin.append(c)
        calles_ant = calles
    # TODO: tal vez se pueda mejorar eso con una custom query sola.
    """
    # solucion 3, como la solucion 2 pero con raw query (para bs as no anda bien)
    if not recorrido.descripcion or not recorrido.descripcion.strip():
        def uniquify(seq, idfun=None):
            if idfun is None:
                def idfun(x):
                    return x
            seen = {}
            result = []
            for item in seq:
                marker = idfun(item)
                if marker in seen:
                    continue
                seen[marker] = 1
                result.append(item)
            return result

        from django.db import connection
        cursor = connection.cursor()
        cursor.execute(
            '''
                SELECT
                    (dp).path[1] as idp,
                    cc.nom       as nom
                FROM
                    (SELECT ST_DumpPoints(%s) as dp ) as dpa
                    JOIN catastro_calle as cc
                    ON ST_DWithin(cc.way, (dp).geom, 20)
            ''',
            (
                recorrido_simplified.ewkb,
            )
        )
        from collections import OrderedDict
        calles = OrderedDict()
        for c in cursor.fetchall():
            if c[0] in calles:
                calles[c[0]].append(c[1])
            else:
                calles[c[0]] = [c[1]]

        calles_fin = []
        calles_ant = []
        for k in calles:
            calles_aca = []
            for c in calles_ant:
                if len(calles_fin) > 0:
                    if c not in calles_fin[-1] and c in calles[k]:
                        calles_aca.append(c)
                else:
                    calles_aca.append(c)
            if calles_aca:
                calles_fin.append(calles_aca)
            calles_ant = calles[k]

        calles_fin = [item for sublist in calles_fin for item in uniquify(sublist)]
    else:
        calles_fin = None

    # POI por los que pasa el recorrido
    pois = Poi.objects.filter(latlng__dwithin=(recorrido_simplified, D(m=400))).order_by('?')[:60]

    # Zonas por las que pasa el recorrido
    aas = AdministrativeArea.objects \
        .filter(geometry_simple__intersects=recorrido_buffer, depth__gt=3) \
        .order_by('depth')

    # Horarios + paradas que tiene este recorrido
    horarios = recorrido.horario_set.all().prefetch_related('parada').order_by('?')[:60]

    recorridos_similares = Recorrido.objects.similar_hausdorff(recorrido_simplified)

    aaancestors, calles_fin, pois, aas, horarios, recorridos_similares = parallelize(aaancestors, calles_fin, pois, aas, horarios, recorridos_similares)

    try:
        schemaorg_itemtype = {
            'bus': 'BusTrip',
            'trolleybus': 'BusTrip',
            'train': 'TrainTrip',
            'subway': 'TrainTrip',
            'monorail': 'TrainTrip',
            'tram': 'TrainTrip',
            'light_rail': 'TrainTrip',
        }[recorrido.type]
    except:
        schemaorg_itemtype = 'Trip'

    context = {
        'schemaorg_itemtype': schemaorg_itemtype,
        'obj': recorrido,
        'linea': recorrido.linea,
        'adminarea': aa,
        'adminareaancestors': aaancestors,
        'calles': calles_fin,
        'pois': pois,
        'adminareas': aas,
        'horarios': horarios,
        'recorridos_similares': recorridos_similares,
    }

    return render(request, "core/ver_recorrido.html", context)
Beispiel #26
0
 def estimate_total_capacity_by_areas(self):
     spots = (self.annotate(spots=Round(PARKING_SPOTS_PER_SQ_M *
                                        Area('geom'))).aggregate(
                                            val=Sum('spots')))['val']
     return int(spots.sq_m) if spots else 0
Beispiel #27
0
 def get_queryset(self):
     boundary_area = Boundary.objects.annotate(
         area=Area("mpoly")).order_by("area")
     return boundary_area
Beispiel #28
0
 def area(self):
     obj = Lake.objects.filter(pk=self.pk).annotate(
         computed_area=Area('the_geom')).get()
     # area is given in sq ft.; however, GeoDjango believes it to be sq m.
     return obj.computed_area.standard / 43560.04
Beispiel #29
0
 def _get_by_area_price(**kwargs):
     polygon = kwargs.get('polygon')
     unit_price = kwargs.get('unit_price')
     area = Area(polygon)
     return unit_price * area