Beispiel #1
0
def get_bbox(instance, crs='EPSG:3857'):
    if crs is None:
        crs = 'EPSG:3857'
    minlon = min(float(instance.bbox_x0), float(instance.bbox_x1))
    minlat = min(float(instance.bbox_y0), float(instance.bbox_y1))
    maxlon = max(float(instance.bbox_x0), float(instance.bbox_x1))
    maxlat = max(float(instance.bbox_y0), float(instance.bbox_y1))

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    # create a buffer
    minlon = max(-180, minlon - lon_range * .1)
    minlat = max(-90, minlat - lat_range * .1)
    maxlon = min(180, maxlon + lon_range * .1)
    maxlat = min(90, maxlat + lat_range * .1)

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    if ratio < 200.0 / 150.0:
        lon_shift = abs(.5 * ((200.0 / 150.0 * lat_range) - lon_range))
        minlon = max(-180, minlon - lon_shift)
        maxlon = min(180, maxlon + lon_shift)
    else:
        adjusted_range = 150.0 / 200.0 * lon_range
        range_delta = adjusted_range - lat_range
        lat_shift = abs(.5 * range_delta)
        minlat = max(-90, minlat - lat_shift)
        maxlat = min(90, maxlat + lat_shift)

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    height = int(200 / ratio)
    logger.debug('height: %s', height)

    if crs == 'EPSG:3857':
        # create bbox in 3857
        minx, miny = forward_mercator([minlon, max(-85.0, minlat)])
        maxx, maxy = forward_mercator([maxlon, min(85.0, maxlat)])
        bbox = '%s,%s,%s,%s' % (minx, miny, maxx, maxy)
        return bbox, height
    elif crs == 'EPSG:4326':
        # deal with weird bbox order for geographic coords in wms 1.3.0
        bbox = '%s,%s,%s,%s' % (minlat, minlon, maxlat, maxlon)
        return bbox, height
    elif crs == 'CRS:84':
        # crs84 bbox
        bbox = '%s,%s,%s,%s' % (minlon, minlat, maxlon, maxlat)
        return bbox, height
    logger.debug('***************Could not determine BBOX***********')
Beispiel #2
0
    def test_forward_mercator(self):
        arctic = forward_mercator((0, 85))
        antarctic = forward_mercator((0, -85))
        hawaii = forward_mercator((-180, 0))
        phillipines = forward_mercator((180, 0))
        ne = forward_mercator((180, 90))
        sw = forward_mercator((-180, -90))

        inf_test = forward_mercator(
            (-8.988465674311579e+307, -8.988465674311579e+307)
        )

        self.assertEqual(inf_test[0], float('-inf'))
        self.assertEqual(inf_test[1], float('-inf'))

        self.assertEqual(round(arctic[0]), 0, "Arctic longitude is correct")
        self.assertEqual(
            round(
                arctic[1]),
            19971869,
            "Arctic latitude is correct")

        self.assertEqual(
            round(
                antarctic[0]),
            0,
            "Antarctic longitude is correct")
        self.assertEqual(
            round(
                antarctic[1]), -19971869, "Antarctic latitude is correct")

        self.assertEqual(
            round(
                hawaii[0]), -20037508, "Hawaiian lon is correct")
        self.assertEqual(round(hawaii[1]), 0, "Hawaiian lat is correct")

        self.assertEqual(
            round(
                phillipines[0]),
            20037508,
            "Phillipines lon is correct")
        self.assertEqual(
            round(
                phillipines[1]),
            0,
            "Phillipines lat is correct")

        self.assertEqual(round(ne[0]), 20037508, "NE lon is correct")
        self.assertTrue(ne[1] > 50000000, "NE lat is correct")

        self.assertEqual(round(sw[0]), -20037508, "SW lon is correct")
        self.assertTrue(math.isinf(sw[1]), "SW lat is correct")

        # verify behavior for invalid y values
        self.assertEqual(float('-inf'), forward_mercator((0, 135))[1])
        self.assertEqual(float('-inf'), forward_mercator((0, -135))[1])
Beispiel #3
0
    def test_forward_mercator(self):
        arctic = forward_mercator((0, 85))
        antarctic = forward_mercator((0, -85))
        hawaii = forward_mercator((-180, 0))
        phillipines = forward_mercator((180, 0))
        ne = forward_mercator((180, 90))
        sw = forward_mercator((-180, -90))

        inf_test = forward_mercator(
            (-8.988465674311579e+307, -8.988465674311579e+307)
        )

        self.assertEqual(inf_test[0], float('-inf'))
        self.assertEqual(inf_test[1], float('-inf'))

        self.assertEqual(round(arctic[0]), 0, "Arctic longitude is correct")
        self.assertEqual(
            round(
                arctic[1]),
            19971869,
            "Arctic latitude is correct")

        self.assertEqual(
            round(
                antarctic[0]),
            0,
            "Antarctic longitude is correct")
        self.assertEqual(
            round(
                antarctic[1]), -19971869, "Antarctic latitude is correct")

        self.assertEqual(
            round(
                hawaii[0]), -20037508, "Hawaiian lon is correct")
        self.assertEqual(round(hawaii[1]), 0, "Hawaiian lat is correct")

        self.assertEqual(
            round(
                phillipines[0]),
            20037508,
            "Phillipines lon is correct")
        self.assertEqual(
            round(
                phillipines[1]),
            0,
            "Phillipines lat is correct")

        self.assertEqual(round(ne[0]), 20037508, "NE lon is correct")
        self.assertTrue(ne[1] > 50000000, "NE lat is correct")

        self.assertEqual(round(sw[0]), -20037508, "SW lon is correct")
        self.assertTrue(math.isinf(sw[1]), "SW lat is correct")

        # verify behavior for invalid y values
        self.assertEqual(float('-inf'), forward_mercator((0, 135))[1])
        self.assertEqual(float('-inf'), forward_mercator((0, -135))[1])
Beispiel #4
0
    def set_bounds_from_bbox(self, bbox):
        """
        Calculate zoom level and center coordinates in mercator.

        :param bbox: BBOX is in the  format: [x0, x1, y0, y1], which is:
            [min lon, max lon, min lat, max lat] or
            [xmin, xmax, ymin, ymax]
        :type bbox: list
        """
        self.set_latlon_bounds(bbox)

        minx, maxx, miny, maxy = [float(c) for c in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2
        (center_x, center_y) = forward_mercator((x, y))

        xdiff = maxx - minx
        ydiff = maxy - miny

        zoom = 0

        if xdiff > 0 and ydiff > 0:
            width_zoom = math.log(360 / xdiff, 2)
            height_zoom = math.log(360 / ydiff, 2)
            zoom = math.ceil(min(width_zoom, height_zoom))

        self.zoom = zoom
        self.center_x = center_x
        self.center_y = center_y
Beispiel #5
0
    def create_from_layer_list(self, user, layers, title, abstract):
        self.owner = user
        self.title = title
        self.abstract = abstract
        self.projection="EPSG:900913"
        self.zoom = 0
        self.center_x = 0
        self.center_y = 0
        map_layers = []
        bbox = None
        index = 0

        DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

        layer_objects = []
        for layer in layers:
            try:
                layer = Layer.objects.get(typename=layer)
            except ObjectDoesNotExist:
                continue # Raise exception?

            if not user.has_perm('maps.view_layer', obj=layer):
                # invisible layer, skip inclusion or raise Exception?
                continue # Raise Exception

            layer_objects.append(layer)

            map_layers.append(MapLayer(
                map = self,
                name = layer.typename,
                ows_url = settings.GEOSERVER_BASE_URL + "wms",
                stack_order = index,
                visibility = True
            ))

            bbox = self.set_bounds_from_layers(layer_objects)

            if bbox is not None:
                minx, maxx, miny, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2
                (self.center_x,self.center_y) = forward_mercator((x,y))

                width_zoom = math.log(360 / (maxx - minx), 2)
                height_zoom = math.log(360 / (maxy - miny), 2)

                self.zoom = math.ceil(min(width_zoom, height_zoom))
            index += 1

        self.save()
        for bl in DEFAULT_BASE_LAYERS:
            bl.map = self
            #bl.save()

        for ml in map_layers:
            ml.map = self # update map_id after saving map
            ml.save()

        self.set_default_permissions()
Beispiel #6
0
    def create_from_layer_list(self, user, layers, title, abstract):
        self.owner = user
        self.title = title
        self.abstract = abstract
        self.projection="EPSG:900913"
        self.zoom = 0
        self.center_x = 0
        self.center_y = 0
        map_layers = []
        bbox = None
        index = 0

        DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

        layer_objects = []
        for layer in layers:
            try:
                layer = Layer.objects.get(typename=layer)
            except ObjectDoesNotExist:
                continue # Raise exception?

            if not user.has_perm('maps.view_layer', obj=layer):
                # invisible layer, skip inclusion or raise Exception?
                continue # Raise Exception

            layer_objects.append(layer)

            map_layers.append(MapLayer(
                map = self,
                name = layer.typename,
                ows_url = layer.ows_url(),
                stack_order = index,
                visibility = True
            ))

            bbox = self.set_bounds_from_layers(layer_objects)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2
                (self.center_x,self.center_y) = forward_mercator((x,y))

                width_zoom = math.log(360 / (maxx - minx), 2)
                height_zoom = math.log(360 / (maxy - miny), 2)

                self.zoom = math.ceil(min(width_zoom, height_zoom))
            index += 1

        self.save()
        for bl in DEFAULT_BASE_LAYERS:
            bl.map = self
            #bl.save()

        for ml in map_layers:
            ml.map = self # update map_id after saving map
            ml.save()

        self.set_default_permissions()
Beispiel #7
0
    def test_inverse_mercator(self):
        arctic = inverse_mercator(forward_mercator((0, 85)))
        antarctic = inverse_mercator(forward_mercator((0, -85)))
        hawaii = inverse_mercator(forward_mercator((-180, 0)))
        phillipines = inverse_mercator(forward_mercator((180, 0)))
        ne = inverse_mercator(forward_mercator((180, 90)))
        sw = inverse_mercator(forward_mercator((-180, -90)))

        self.assertAlmostEqual(arctic[0], 0.0, msg="Arctic longitude is correct")
        self.assertAlmostEqual(arctic[1], 85.0, msg="Arctic latitude is correct")

        self.assertAlmostEqual(antarctic[0], 0.0, msg="Antarctic longitude is correct")
        self.assertAlmostEqual(antarctic[1], -85.0, msg="Antarctic latitude is correct")

        self.assertAlmostEqual(hawaii[0], -180.0, msg="Hawaiian lon is correct")
        self.assertAlmostEqual(hawaii[1], 0.0, msg="Hawaiian lat is correct")

        self.assertAlmostEqual(phillipines[0], 180.0, msg="Phillipines lon is correct")
        self.assertAlmostEqual(phillipines[1], 0.0, msg="Phillipines lat is correct")

        self.assertAlmostEqual(ne[0], 180.0, msg="NE lon is correct")
        self.assertAlmostEqual(ne[1], 90.0, msg="NE lat is correct")

        self.assertAlmostEqual(sw[0], -180.0, msg="SW lon is correct")
        self.assertAlmostEqual(sw[1], -90.0, msg="SW lat is correct")
Beispiel #8
0
    def set_bounds_from_bbox(self, bbox, srid):
        """
        Calculate zoom level and center coordinates in mercator.

        :param bbox: BBOX is in the  format: [x0, x1, y0, y1], which is:
            [min lon, max lon, min lat, max lat] or
            [xmin, xmax, ymin, ymax]
        :type bbox: list
        """
        if not bbox or len(bbox) < 4:
            raise ValidationError(
                'Bounding Box cannot be empty %s for a given resource' %
                self.name)
        if not srid:
            raise ValidationError(
                'Projection cannot be empty %s for a given resource' %
                self.name)
        self.bbox_x0 = bbox[0]
        self.bbox_x1 = bbox[1]
        self.bbox_y0 = bbox[2]
        self.bbox_y1 = bbox[3]
        self.srid = srid

        if srid == "EPSG:4326":
            minx, maxx, miny, maxy = [float(c) for c in bbox]
            x = (minx + maxx) / 2
            y = (miny + maxy) / 2
            (center_x, center_y) = forward_mercator((x, y))

            xdiff = maxx - minx
            ydiff = maxy - miny

            zoom = 0

            if xdiff > 0 and ydiff > 0:
                width_zoom = math.log(360 / xdiff, 2)
                height_zoom = math.log(360 / ydiff, 2)
                zoom = math.ceil(min(width_zoom, height_zoom))

            try:
                self.zoom = zoom
                self.center_x = center_x
                self.center_y = center_y
            except BaseException:
                pass
Beispiel #9
0
    def set_bounds_from_bbox(self, bbox, srid):
        """
        Calculate zoom level and center coordinates in mercator.

        :param bbox: BBOX is in the  format: [x0, x1, y0, y1], which is:
            [min lon, max lon, min lat, max lat] or
            [xmin, xmax, ymin, ymax]
        :type bbox: list
        """
        if not bbox or len(bbox) < 4:
            raise ValidationError(
                'Bounding Box cannot be empty %s for a given resource' %
                self.name)
        if not srid:
            raise ValidationError(
                'Projection cannot be empty %s for a given resource' %
                self.name)
        self.bbox_x0 = bbox[0]
        self.bbox_x1 = bbox[1]
        self.bbox_y0 = bbox[2]
        self.bbox_y1 = bbox[3]
        self.srid = srid

        if srid == "EPSG:4326":
            minx, maxx, miny, maxy = [float(c) for c in bbox]
            x = (minx + maxx) / 2
            y = (miny + maxy) / 2
            (center_x, center_y) = forward_mercator((x, y))

            xdiff = maxx - minx
            ydiff = maxy - miny

            zoom = 0

            if xdiff > 0 and ydiff > 0:
                width_zoom = math.log(360 / xdiff, 2)
                height_zoom = math.log(360 / ydiff, 2)
                zoom = math.ceil(min(width_zoom, height_zoom))

            try:
                self.zoom = zoom
                self.center_x = center_x
                self.center_y = center_y
            except BaseException:
                pass
Beispiel #10
0
def set_bounds_from_bbox(bbox):
        """
        Calculate zoom level and center coordinates in mercator.
        """
        minx, miny, maxx, maxy = [float(c) for c in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2
        (center_x, center_y) = forward_mercator((y, x))

        xdiff = maxx - minx
        ydiff = maxy - miny

        zoom = 0

        if xdiff > 0 and ydiff > 0:
            width_zoom = math.log(360 / xdiff, 2)
            height_zoom = math.log(360 / ydiff, 2)
            zoom = math.ceil(min(width_zoom, height_zoom))

        zoom = zoom
        center_x = center_x
        center_y = center_y
        return zoom, center_x, center_y
Beispiel #11
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user

        config = map_obj.viewer_json(request.user, access_token)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS',
                          'EPSG:900913'))
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm(
                        'view_resourcebase',
                        obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["title"] = layer.title
                config["queryable"] = True

                config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
                config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
                    else llbbox_to_mercator([float(coord) for coord in bbox])

                if layer.storeType == "remoteStore":
                    service = layer.service
                    # Probably not a good idea to send the access token to every remote service.
                    # This should never match, so no access token should be sent to remote services.
                    ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc
                    service_url = urlparse.urlsplit(service.base_url).netloc

                    if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                        url = service.base_url+'?access_token='+access_token
                    else:
                        url = service.base_url
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype": service.ptype,
                                            "remote": True,
                                            "url": url,
                                            "name": service.name}))
                else:
                    ogc_server_url = urlparse.urlsplit(ogc_server_settings.PUBLIC_LOCATION).netloc
                    layer_url = urlparse.urlsplit(layer.ows_url).netloc

                    if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                        url = layer.ows_url+'?access_token='+access_token
                    else:
                        url = layer.ows_url
                    maplayer = MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=url,
                        # use DjangoJSONEncoder to handle Decimal values
                        layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                        visibility=True
                    )

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(coord) for coord in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326":
                    center = list((x, y))
                else:
                    center = list(forward_mercator((x, y)))

                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(
                request.user, access_token, *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
Beispiel #12
0
def layer_detail(request, layername, template='layers/layer_detail.html'):
    layer = _resolve_layer(
        request,
        layername,
        'base.view_resourcebase',
        _("You are not permitted to view this layer"))

    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # Add required parameters for GXP lazy-loading
    layer_bbox = layer.bbox
    bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
    config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
        else llbbox_to_mercator([float(coord) for coord in bbox])
    config["title"] = layer.title
    config["queryable"] = True
    if layer.default_style:
        config["styles"] = layer.default_style.name

    if layer.storeType == "remoteStore":
        source_srid = None
        # Only grab the service proj/bbox if it is valid
        if None not in layer.service.bbox[0:4]:
            bbox = [float(coord) for coord in list(layer.service.bbox[0:4])]
            source_srid = layer.service.srid
        # Otherwise try the service directly
        # This is needed since previous services registered
        # did not store the bbox/srid in the model
        else:
            try:
                service_handler = get_service_handler(
                    base_url=layer.service.base_url,
                    service_type=layer.service.type)
                if getattr(service_handler.parsed_service, 'initialExtent',
                           None):
                    bbox[0] = service_handler.parsed_service.initialExtent[
                        'xmin']
                    bbox[1] = service_handler.parsed_service.initialExtent[
                        'ymin']
                    bbox[2] = service_handler.parsed_service.initialExtent[
                        'xmax']
                    bbox[3] = service_handler.parsed_service.initialExtent[
                        'ymax']
                else:
                    logger.info('Could not retrieve extent from service: {0}'
                                .format(layer.service))
                if getattr(service_handler.parsed_service, 'spatialReference',
                           None):
                    source_srid = \
                        service_handler.parsed_service.spatialReference[
                            'latestWkid']
                else:
                    logger.info('Could not retrieve srid from service: {0}'
                                .format(layer.service))
            except Exception as e:
                logger.info('Failed to access service endpoint: {0}'
                            .format(layer.service.base_url))
                logger.info('Caught error: {0}'.format(e))
        if source_srid is None:
            source_srid = layer.srid
        target_srid = 3857 if config["srs"] == 'EPSG:900913' else config["srs"]
        reprojected_bbox = bbox_to_projection(bbox, source_srid=source_srid,
                                              target_srid=target_srid)
        bbox = reprojected_bbox[:4]
        config['bbox'] = [float(coord) for coord in bbox]
        service = layer.service
        source_url = service.base_url
        use_proxy = (callable(uses_proxy_route) and
                     uses_proxy_route(service.base_url))
        components = urlsplit(service.base_url)
        query_params = None
        if components.query:
            query_params = OrderedDict(
                parse_qsl(components.query, keep_blank_values=True))
            removed_query = [components.scheme, components.netloc,
                             components.path,
                             None, components.fragment]
            source_url = urlunsplit(removed_query)
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": source_url,
            "name": service.name,
            "use_proxy": use_proxy}
        if query_params is not None:
            source_params["params"] = query_params
        if layer.alternate is not None:
            config["layerid"] = layer.alternate
        maplayer = GXPLayer(
            name=layer.typename,
            ows_url=layer.ows_url,
            layer_params=json.dumps(config),
            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(
            name=layer.typename,
            ows_url=layer.ows_url,
            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(
            id=layer.id).update(popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(
        projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'))

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    granules = None
    all_granules = None
    filter = None
    if layer.is_mosaic:
        try:
            cat = gs_catalog
            cat._cache.clear()
            store = cat.get_store(layer.name)
            coverages = cat.mosaic_coverages(store)

            filter = None
            try:
                if request.GET["filter"]:
                    filter = request.GET["filter"]
            except:
                pass

            offset = 10 * (request.page - 1)
            granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'], store, limit=10,
                offset=offset, filter=filter)
            all_granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'], store,
                filter=filter)
        except:
            granules = {"features": []}
            all_granules = {"features": []}

    context_dict = {
        "resource": layer,
        'perms_list': get_perms(request.user, layer.get_self_resource()),
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "granules": granules,
        "all_granules": all_granules,
        "filter": filter,
    }

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        u = uuid.uuid1()
        access_token = u.hex

    if bbox is not None:
        minx, miny, maxx, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if layer.is_remote or getattr(settings, 'DEFAULT_MAP_CRS',
                                      'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, access_token,
                            *(default_map_config(request)[1] + [maplayer])))

    context_dict["preview"] = getattr(
        settings,
        'LAYER_PREVIEW_LIBRARY',
        'leaflet')
    context_dict["crs"] = getattr(
        settings,
        'DEFAULT_MAP_CRS',
        'EPSG:900913')

    if layer.storeType == 'dataStore':
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_VECTOR)
    else:
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_RASTER)
    links_view = [item for idx, item in enumerate(links) if
                  item.url and 'wms' in item.url or 'gwc' in item.url]
    links_download = [item for idx, item in enumerate(links) if
                      item.url and 'wms' not in item.url and
                      'gwc' not in item.url]
    for item in links_view:
        if item.url and access_token:
            item.url = "%s&access_token=%s&time=%s" % \
                       (item.url, access_token, "0/9999")
    for item in links_download:
        if item.url and access_token:
            item.url = "%s&access_token=%s" % (item.url, access_token)

    if request.user.has_perm('view_resourcebase', layer.get_self_resource()):
        context_dict["links"] = links_view
    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links_download"] = links_download

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    return render_to_response(template, RequestContext(request, context_dict))
Beispiel #13
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user
        config = map_obj.viewer_json(request.user)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(
                projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'))
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm('view_resourcebase',
                                             obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["title"] = layer.title
                config["queryable"] = True

                config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS',
                                        'EPSG:900913')
                config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
                    else llbbox_to_mercator([float(coord) for coord in bbox])

                if layer.storeType == "remoteStore":
                    service = layer.service
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype":
                                            service.ptype,
                                            "remote":
                                            True,
                                            "url":
                                            service.base_url,
                                            "name":
                                            service.name
                                        }))
                else:
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True)

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                if getattr(settings, 'DEFAULT_MAP_CRS',
                           'EPSG:900913') == "EPSG:4326":
                    center = list((x, y))
                else:
                    center = list(forward_mercator((x, y)))

                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(request.user,
                                         *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
Beispiel #14
0
def layer_detail(request, layername, template='layers/layer_detail.html'):
    layer = _resolve_layer(request, layername, 'base.view_resourcebase',
                           _("You are not permitted to view this layer"))

    # assert False, str(layer_bbox)
    config = layer.attribute_config()

    # Add required parameters for GXP lazy-loading
    layer_bbox = layer.bbox
    bbox = [float(coord) for coord in list(layer_bbox[0:4])]
    config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
    config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
        else llbbox_to_mercator([float(coord) for coord in bbox])
    config["title"] = layer.title
    config["queryable"] = True
    if layer.default_style:
        config["styles"] = layer.default_style.name

    if layer.storeType == "remoteStore":
        source_srid = None
        # Only grab the service proj/bbox if it is valid
        if None not in layer.service.bbox[0:4]:
            bbox = [float(coord) for coord in list(layer.service.bbox[0:4])]
            source_srid = layer.service.srid
        # Otherwise try the service directly
        # This is needed since previous services registered
        # did not store the bbox/srid in the model
        else:
            try:
                service_handler = get_service_handler(
                    base_url=layer.service.base_url,
                    service_type=layer.service.type)
                if getattr(service_handler.parsed_service, 'initialExtent',
                           None):
                    bbox[0] = service_handler.parsed_service.initialExtent[
                        'xmin']
                    bbox[1] = service_handler.parsed_service.initialExtent[
                        'ymin']
                    bbox[2] = service_handler.parsed_service.initialExtent[
                        'xmax']
                    bbox[3] = service_handler.parsed_service.initialExtent[
                        'ymax']
                else:
                    logger.info(
                        'Could not retrieve extent from service: {0}'.format(
                            layer.service))
                if getattr(service_handler.parsed_service, 'spatialReference',
                           None):
                    source_srid = \
                        service_handler.parsed_service.spatialReference[
                            'latestWkid']
                else:
                    logger.info(
                        'Could not retrieve srid from service: {0}'.format(
                            layer.service))
            except Exception as e:
                logger.info('Failed to access service endpoint: {0}'.format(
                    layer.service.base_url))
                logger.info('Caught error: {0}'.format(e))
        if source_srid is None:
            source_srid = layer.srid
        target_srid = 3857 if config["srs"] == 'EPSG:900913' else config["srs"]
        reprojected_bbox = bbox_to_projection(bbox,
                                              source_srid=source_srid,
                                              target_srid=target_srid)
        bbox = reprojected_bbox[:4]
        config['bbox'] = [float(coord) for coord in bbox]
        service = layer.service
        source_url = service.base_url
        use_proxy = (callable(uses_proxy_route)
                     and uses_proxy_route(service.base_url))
        components = urlsplit(service.base_url)
        query_params = None
        if components.query:
            query_params = OrderedDict(
                parse_qsl(components.query, keep_blank_values=True))
            removed_query = [
                components.scheme, components.netloc, components.path, None,
                components.fragment
            ]
            source_url = urlunsplit(removed_query)
        source_params = {
            "ptype": service.ptype,
            "remote": True,
            "url": source_url,
            "name": service.name,
            "use_proxy": use_proxy
        }
        if query_params is not None:
            source_params["params"] = query_params
        if layer.alternate is not None:
            config["layerid"] = layer.alternate
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config),
                            source_params=json.dumps(source_params))
    else:
        maplayer = GXPLayer(name=layer.typename,
                            ows_url=layer.ows_url,
                            layer_params=json.dumps(config))

    # Update count for popularity ranking,
    # but do not includes admins or resource owners
    if request.user != layer.owner and not request.user.is_superuser:
        Layer.objects.filter(id=layer.id).update(
            popular_count=F('popular_count') + 1)

    # center/zoom don't matter; the viewer will center on the layer bounds
    map_obj = GXPMap(
        projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'))

    metadata = layer.link_set.metadata().filter(
        name__in=settings.DOWNLOAD_FORMATS_METADATA)

    granules = None
    all_granules = None
    filter = None
    if layer.is_mosaic:
        try:
            cat = gs_catalog
            cat._cache.clear()
            store = cat.get_store(layer.name)
            coverages = cat.mosaic_coverages(store)

            filter = None
            try:
                if request.GET["filter"]:
                    filter = request.GET["filter"]
            except:
                pass

            offset = 10 * (request.page - 1)
            granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                limit=10,
                offset=offset,
                filter=filter)
            all_granules = cat.mosaic_granules(
                coverages['coverages']['coverage'][0]['name'],
                store,
                filter=filter)
        except:
            granules = {"features": []}
            all_granules = {"features": []}

    context_dict = {
        "resource": layer,
        'perms_list': get_perms(request.user, layer.get_self_resource()),
        "permissions_json": _perms_info_json(layer),
        "documents": get_related_documents(layer),
        "metadata": metadata,
        "is_layer": True,
        "wps_enabled": settings.OGC_SERVER['default']['WPS_ENABLED'],
        "granules": granules,
        "all_granules": all_granules,
        "filter": filter,
    }

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        u = uuid.uuid1()
        access_token = u.hex

    if bbox is not None:
        minx, miny, maxx, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if layer.is_remote or getattr(settings, 'DEFAULT_MAP_CRS',
                                      'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    context_dict["viewer"] = json.dumps(
        map_obj.viewer_json(request.user, access_token,
                            *(default_map_config(request)[1] + [maplayer])))

    context_dict["preview"] = getattr(settings, 'LAYER_PREVIEW_LIBRARY',
                                      'leaflet')
    context_dict["crs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')

    if layer.storeType == 'dataStore':
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_VECTOR)
    else:
        links = layer.link_set.download().filter(
            name__in=settings.DOWNLOAD_FORMATS_RASTER)
    links_view = [
        item for idx, item in enumerate(links)
        if item.url and 'wms' in item.url or 'gwc' in item.url
    ]
    links_download = [
        item for idx, item in enumerate(links)
        if item.url and 'wms' not in item.url and 'gwc' not in item.url
    ]
    for item in links_view:
        if item.url and access_token:
            item.url = "%s&access_token=%s&time=%s" % \
                       (item.url, access_token, "0/9999")
    for item in links_download:
        if item.url and access_token:
            item.url = "%s&access_token=%s" % (item.url, access_token)

    if request.user.has_perm('view_resourcebase', layer.get_self_resource()):
        context_dict["links"] = links_view
    if request.user.has_perm('download_resourcebase',
                             layer.get_self_resource()):
        if layer.storeType == 'dataStore':
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_VECTOR)
        else:
            links = layer.link_set.download().filter(
                name__in=settings.DOWNLOAD_FORMATS_RASTER)
        context_dict["links_download"] = links_download

    if settings.SOCIAL_ORIGINS:
        context_dict["social_links"] = build_social_links(request, layer)

    return render_to_response(template, RequestContext(request, context_dict))
Beispiel #15
0
def add_layers_to_map_config(request,
                             map_obj,
                             layer_names,
                             add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)
    bbox = None
    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue

        if not layer.is_published:
            # invisible layer, skip inclusion
            continue

        if not request.user.has_perm('view_resourcebase',
                                     obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox
        # assert False, str(layer_bbox)
        if bbox is None:
            bbox = list(layer_bbox[0:4])
        else:
            bbox[0] = min(bbox[0], layer_bbox[0])
            bbox[1] = max(bbox[1], layer_bbox[1])
            bbox[2] = min(bbox[2], layer_bbox[2])
            bbox[3] = max(bbox[3], layer_bbox[3])

        config = layer.attribute_config()

        # Add required parameters for a WM layer
        title = 'No title'
        if layer.title:
            title = layer.title
        config["title"] = title
        config["queryable"] = True

        config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')

        config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
            else llbbox_to_mercator([float(coord) for coord in bbox])

        if layer.storeType == "remoteStore":
            service = layer.service
            # Probably not a good idea to send the access token to every remote service.
            # This should never match, so no access token should be
            # sent to remote services.
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            service_url = urlparse.urlsplit(service.base_url).netloc

            access_token = request.session[
                'access_token'] if request and 'access_token' in request.session else None
            if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                url = service.base_url + '?access_token=' + access_token
            else:
                url = service.base_url
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps({
                                    "ptype": service.ptype,
                                    "remote": True,
                                    "url": url,
                                    "name": service.name
                                }))
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = layer.ows_url + '?access_token=' + access_token
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True)
        layers.append(maplayer)

    if bbox is not None:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(request, *layers_to_add)

    config['fromLayer'] = True

    return config
Beispiel #16
0
def add_layers_to_map_config(request, map_obj, layer_names, add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)
    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    bbox = None

    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue

        if not layer.is_published:
            # invisible layer, skip inclusion
            continue

        if not request.user.has_perm(
                'view_resourcebase',
                obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox
        # assert False, str(layer_bbox)
        if bbox is None:
            bbox = list(layer_bbox[0:4])
        else:
            bbox[0] = min(bbox[0], layer_bbox[0])
            bbox[1] = max(bbox[1], layer_bbox[1])
            bbox[2] = min(bbox[2], layer_bbox[2])
            bbox[3] = max(bbox[3], layer_bbox[3])

        config = layer.attribute_config()

        # Add required parameters for GXP lazy-loading
        config["title"] = layer.title
        config["queryable"] = True
        config["wrapDateLine"] = True

        config["srs"] = getattr(
            settings, 'DEFAULT_MAP_CRS', 'EPSG:900913')
        config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
            else llbbox_to_mercator([float(coord) for coord in bbox])

        if layer.storeType == "remoteStore":
            service = layer.service
            # Probably not a good idea to send the access token to every remote service.
            # This should never match, so no access token should be
            # sent to remote services.
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            service_url = urlparse.urlsplit(service.base_url).netloc

            if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                url = service.base_url + '?access_token=' + access_token
            else:
                url = service.base_url
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps({
                                    "ptype": service.ptype,
                                    "remote": True,
                                    "url": url,
                                    "name": service.name}))
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = layer.ows_url + '?access_token=' + access_token
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True
            )

        layers.append(maplayer)

    if bbox is not None:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(
            settings,
            'DEFAULT_MAP_CRS',
                'EPSG:900913') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(
        request.user, access_token, *layers_to_add)

    config['fromLayer'] = True

    return config
Beispiel #17
0
def add_layers_to_map_config(request,
                             map_obj,
                             layer_names,
                             add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)
    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    bbox = []
    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue

        if not layer.is_published:
            # invisible layer, skip inclusion
            continue

        if not request.user.has_perm('view_resourcebase',
                                     obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox[0:4]
        bbox = layer_bbox[:]
        bbox[0] = layer_bbox[0]
        bbox[1] = layer_bbox[2]
        bbox[2] = layer_bbox[1]
        bbox[3] = layer_bbox[3]

        # assert False, str(layer_bbox)

        def decimal_encode(bbox):
            import decimal
            _bbox = []
            for o in [float(coord) for coord in bbox]:
                if isinstance(o, decimal.Decimal):
                    o = (str(o) for o in [o])
                _bbox.append(o)
            return _bbox

        def sld_definition(style):
            from urllib import quote
            _sld = {
                "title": style.sld_title or style.name,
                "legend": {
                    "height":
                    "40",
                    "width":
                    "22",
                    "href":
                    layer.ows_url +
                    "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer="
                    + quote(layer.service_typename, safe=''),
                    "format":
                    "image/png"
                },
                "name": style.name
            }
            return _sld

        config = layer.attribute_config()
        if hasattr(layer, 'srid'):
            config['crs'] = {'type': 'name', 'properties': layer.srid}
        # Add required parameters for GXP lazy-loading
        attribution = "%s %s" % (
            layer.owner.first_name, layer.owner.last_name
        ) if layer.owner.first_name or layer.owner.last_name else str(
            layer.owner)
        srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')
        srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857
        config[
            "attribution"] = "<span class='gx-attribution-title'>%s</span>" % attribution
        config["format"] = getattr(settings, 'DEFAULT_LAYER_FORMAT',
                                   'image/png')
        config["title"] = layer.title
        config["wrapDateLine"] = True
        config["visibility"] = True
        config["srs"] = srs
        config["bbox"] = decimal_encode(
            bbox_to_projection([float(coord) for coord in layer_bbox] + [
                layer.srid,
            ],
                               target_srid=int(srs.split(":")[1]))[:4])
        config["capability"] = {
            "abstract":
            layer.abstract,
            "name":
            layer.alternate,
            "title":
            layer.title,
            "queryable":
            True,
            "bbox": {
                layer.srid: {
                    "srs": layer.srid,
                    "bbox": decimal_encode(bbox)
                },
                srs: {
                    "srs":
                    srs,
                    "bbox":
                    decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=srs_srid)[:4])
                },
                "EPSG:4326": {
                    "srs":
                    "EPSG:4326",
                    "bbox":
                    decimal_encode(bbox)
                    if layer.srid == 'EPSG:4326' else decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=4326)[:4])
                },
                "EPSG:900913": {
                    "srs":
                    "EPSG:900913",
                    "bbox":
                    decimal_encode(bbox)
                    if layer.srid == 'EPSG:900913' else decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=3857)[:4])
                }
            },
            "srs": {
                srs: True
            },
            "formats": [
                "image/png", "application/atom xml", "application/atom+xml",
                "application/json;type=utfgrid", "application/openlayers",
                "application/pdf", "application/rss xml",
                "application/rss+xml", "application/vnd.google-earth.kml",
                "application/vnd.google-earth.kml xml",
                "application/vnd.google-earth.kml+xml",
                "application/vnd.google-earth.kml+xml;mode=networklink",
                "application/vnd.google-earth.kmz",
                "application/vnd.google-earth.kmz xml",
                "application/vnd.google-earth.kmz+xml",
                "application/vnd.google-earth.kmz;mode=networklink", "atom",
                "image/geotiff", "image/geotiff8", "image/gif",
                "image/gif;subtype=animated", "image/jpeg", "image/png8",
                "image/png; mode=8bit", "image/svg", "image/svg xml",
                "image/svg+xml", "image/tiff", "image/tiff8",
                "image/vnd.jpeg-png", "kml", "kmz", "openlayers", "rss",
                "text/html; subtype=openlayers", "utfgrid"
            ],
            "attribution": {
                "title": attribution
            },
            "infoFormats": [
                "text/plain", "application/vnd.ogc.gml", "text/xml",
                "application/vnd.ogc.gml/3.1.1", "text/xml; subtype=gml/3.1.1",
                "text/html", "application/json"
            ],
            "styles": [sld_definition(s) for s in layer.styles.all()],
            "prefix":
            layer.alternate.split(":")[0] if ":" in layer.alternate else "",
            "keywords":
            [k.name for k in layer.keywords.all()] if layer.keywords else [],
            "llbbox":
            decimal_encode(bbox)
            if layer.srid == 'EPSG:4326' else decimal_encode(
                bbox_to_projection([float(coord) for coord in layer_bbox] + [
                    layer.srid,
                ],
                                   target_srid=4326)[:4])
        }

        if layer.storeType == "remoteStore":
            service = layer.remote_service
            source_params = {
                "ptype": service.ptype,
                "remote": True,
                "url": service.service_url,
                "name": service.name,
                "title": "[R] %s" % service.title
            }
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps(source_params))
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = layer.ows_url + '?access_token=' + access_token
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True)

        layers.append(maplayer)

    if bbox is not None:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(request.user, access_token, *layers_to_add)

    config['fromLayer'] = True
    return config
Beispiel #18
0
def new_map_config(request):
    """
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    """
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == "GET" and "copy" in request.GET:
        mapid = request.GET["copy"]
        map_obj = _resolve_map(request, mapid, "maps.view_map")

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user
        config = map_obj.viewer_json()
        del config["id"]
    else:
        if request.method == "GET":
            params = request.GET
        elif request.method == "POST":
            params = request.POST
        else:
            return HttpResponse(status=405)

        if "layer" in params:
            bbox = None
            map_obj = Map(projection="EPSG:900913")
            layers = []
            for layer_name in params.getlist("layer"):
                try:
                    layer = Layer.objects.get(typename=layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm("layers.view_layer", obj=layer):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                layers.append(
                    MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=ogc_server_settings.public_url + "wms",
                        layer_params=json.dumps(layer.attribute_config()),
                        visibility=True,
                    )
                )

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                center = forward_mercator((x, y))
                if center[1] == float("-inf"):
                    center[1] = 0

                if maxx == minx:
                    width_zoom = 15
                else:
                    width_zoom = math.log(360 / (maxx - minx), 2)
                if maxy == miny:
                    height_zoom = 15
                else:
                    height_zoom = math.log(360 / (maxy - miny), 2)

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(*(DEFAULT_BASE_LAYERS + layers))
            config["fromLayer"] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
Beispiel #19
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''

    # 3 cases in this function
    # 1. copy a map
    # 2. a new map with one or more layers
    # 3. a new map with no layers

    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

    if 'access_token' in request.session:
        access_token = request.session['access_token']
    else:
        access_token = None

    # TODO support map copy
    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user

        config = map_obj.viewer_json(request.user, access_token)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        # a new map with a layer
        if 'layer' in params:
            bbox = None
            map_obj = Map(
                projection=getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:900913'))

            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm('view_resourcebase',
                                             obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["title"] = layer.title
                config["queryable"] = True

                config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS',
                                        'EPSG:900913')
                config["bbox"] = bbox if config["srs"] != 'EPSG:900913' \
                    else llbbox_to_mercator([float(coord) for coord in bbox])

                if layer.storeType == "remoteStore":
                    service = layer.service
                    # Probably not a good idea to send the access token to every remote service.
                    # This should never match, so no access token should be sent to remote services.
                    ogc_server_url = urlparse.urlsplit(
                        ogc_server_settings.PUBLIC_LOCATION).netloc
                    service_url = urlparse.urlsplit(service.base_url).netloc

                    if access_token and ogc_server_url == service_url and 'access_token' not in service.base_url:
                        url = service.base_url + '?access_token=' + access_token
                    else:
                        url = service.base_url
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype":
                                            service.ptype,
                                            "remote":
                                            True,
                                            "url":
                                            url,
                                            "name":
                                            service.name
                                        }))
                else:
                    ogc_server_url = urlparse.urlsplit(
                        ogc_server_settings.PUBLIC_LOCATION).netloc
                    layer_url = urlparse.urlsplit(layer.ows_url).netloc

                    if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                        url = layer.ows_url + '?access_token=' + access_token
                    else:
                        url = layer.ows_url
                    maplayer = MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=url,
                        # use DjangoJSONEncoder to handle Decimal values
                        layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                        visibility=True)

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(coord) for coord in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                if getattr(settings, 'DEFAULT_MAP_CRS',
                           'EPSG:900913') == "EPSG:4326":
                    center = list((x, y))
                else:
                    center = list(forward_mercator((x, y)))

                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(request.user, access_token,
                                         *(DEFAULT_BASE_LAYERS + layers))

            config['fromLayer'] = True
            geoexplorer2worldmap(config, map_obj, layers)
        else:
            # a new map with no layer
            config = DEFAULT_MAP_CONFIG
            geoexplorer2worldmap(config, map_obj)

    return json.dumps(config)
Beispiel #20
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'maps.view_map')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated(): map_obj.owner = request.user
        config = map_obj.viewer_json()
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection="EPSG:900913")
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = Layer.objects.get(typename=layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm('layers.view_layer', obj=layer):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                layers.append(
                    MapLayer(map=map_obj,
                             name=layer.typename,
                             ows_url=layer.ows_url(),
                             layer_params=json.dumps(layer.attribute_config()),
                             visibility=True))

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                center = forward_mercator((x, y))
                if center[1] == float('-inf'):
                    center[1] = 0

                if maxx == minx:
                    width_zoom = 15
                else:
                    width_zoom = math.log(360 / (maxx - minx), 2)
                if maxy == miny:
                    height_zoom = 15
                else:
                    height_zoom = math.log(360 / (maxy - miny), 2)

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(*(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
Beispiel #21
0
def map_embed_widget(request,
                     mapid,
                     template='leaflet/maps/map_embed_widget.html'):
    """Display code snippet for embedding widget.

    :param request: The request from the frontend.
    :type request: HttpRequest

    :param mapid: The id of the map.
    :type mapid: String

    :return: formatted code.
    """

    map_obj = _resolve_map(request, mapid, 'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)
    map_bbox = map_obj.bbox_string.split(',')

    map_layers = MapLayer.objects.filter(map_id=mapid).order_by('stack_order')
    layers = []
    for layer in map_layers:
        if layer.group != 'background':
            layers.append(layer)

    if map_obj.srid != 'EPSG:3857':
        map_bbox = [float(coord) for coord in map_bbox]
    else:
        map_bbox = llbbox_to_mercator([float(coord) for coord in map_bbox])

    if map_bbox is not None:
        minx, miny, maxx, maxy = [float(coord) for coord in map_bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS') == "EPSG:3857":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    context = {'resource': map_obj, 'map_bbox': map_bbox, 'map_layers': layers}
    message = render(request, template, context)
    return HttpResponse(message)
Beispiel #22
0
def add_layers_to_map_config(request,
                             map_obj,
                             layer_names,
                             add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

    bbox = []
    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue
        except Http404:
            # can't find the layer, skip it.
            continue

        if not request.user.has_perm('view_resourcebase',
                                     obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox[0:4]
        bbox = layer_bbox[:]
        bbox[0] = layer_bbox[0]
        bbox[1] = layer_bbox[2]
        bbox[2] = layer_bbox[1]
        bbox[3] = layer_bbox[3]

        # assert False, str(layer_bbox)

        def decimal_encode(bbox):
            import decimal
            _bbox = []
            for o in [float(coord) for coord in bbox]:
                if isinstance(o, decimal.Decimal):
                    o = (str(o) for o in [o])
                _bbox.append(o)
            # Must be in the form : [x0, x1, y0, y1
            return [_bbox[0], _bbox[2], _bbox[1], _bbox[3]]

        def sld_definition(style):
            _sld = {
                "title": style.sld_title or style.name,
                "legend": {
                    "height":
                    "40",
                    "width":
                    "22",
                    "href":
                    layer.ows_url +
                    "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer="
                    + quote(layer.service_typename, safe=''),
                    "format":
                    "image/png"
                },
                "name": style.name
            }
            return _sld

        config = layer.attribute_config()
        if hasattr(layer, 'srid'):
            config['crs'] = {'type': 'name', 'properties': layer.srid}
        # Add required parameters for GXP lazy-loading
        attribution = "%s %s" % (
            layer.owner.first_name, layer.owner.last_name
        ) if layer.owner.first_name or layer.owner.last_name else str(
            layer.owner)
        srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')
        srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857
        config[
            "attribution"] = "<span class='gx-attribution-title'>%s</span>" % attribution
        config["format"] = getattr(settings, 'DEFAULT_LAYER_FORMAT',
                                   'image/png')
        config["title"] = layer.title
        config["wrapDateLine"] = True
        config["visibility"] = True
        config["srs"] = srs
        config["bbox"] = decimal_encode(
            bbox_to_projection([float(coord) for coord in layer_bbox] + [
                layer.srid,
            ],
                               target_srid=int(srs.split(":")[1]))[:4])
        config["capability"] = {
            "abstract":
            layer.abstract,
            "store":
            layer.store,
            "name":
            layer.alternate,
            "title":
            layer.title,
            "queryable":
            True,
            "storeType":
            layer.storeType,
            "bbox": {
                layer.srid: {
                    "srs": layer.srid,
                    "bbox": decimal_encode(bbox)
                },
                srs: {
                    "srs":
                    srs,
                    "bbox":
                    decimal_encode(
                        bbox_to_projection(
                            [float(coord) for coord in layer_bbox] + [
                                layer.srid,
                            ],
                            target_srid=srs_srid)[:4])
                },
                "EPSG:4326": {
                    "srs":
                    "EPSG:4326",
                    "bbox":
                    decimal_encode(bbox) if layer.srid == 'EPSG:4326' else
                    bbox_to_projection([float(coord)
                                        for coord in layer_bbox] + [
                                            layer.srid,
                                        ],
                                       target_srid=4326)[:4]
                },
                "EPSG:900913": {
                    "srs":
                    "EPSG:900913",
                    "bbox":
                    decimal_encode(bbox) if layer.srid == 'EPSG:900913' else
                    bbox_to_projection([float(coord)
                                        for coord in layer_bbox] + [
                                            layer.srid,
                                        ],
                                       target_srid=3857)[:4]
                }
            },
            "srs": {
                srs: True
            },
            "formats": [
                "image/png", "application/atom xml", "application/atom+xml",
                "application/json;type=utfgrid", "application/openlayers",
                "application/pdf", "application/rss xml",
                "application/rss+xml", "application/vnd.google-earth.kml",
                "application/vnd.google-earth.kml xml",
                "application/vnd.google-earth.kml+xml",
                "application/vnd.google-earth.kml+xml;mode=networklink",
                "application/vnd.google-earth.kmz",
                "application/vnd.google-earth.kmz xml",
                "application/vnd.google-earth.kmz+xml",
                "application/vnd.google-earth.kmz;mode=networklink", "atom",
                "image/geotiff", "image/geotiff8", "image/gif",
                "image/gif;subtype=animated", "image/jpeg", "image/png8",
                "image/png; mode=8bit", "image/svg", "image/svg xml",
                "image/svg+xml", "image/tiff", "image/tiff8",
                "image/vnd.jpeg-png", "kml", "kmz", "openlayers", "rss",
                "text/html; subtype=openlayers", "utfgrid"
            ],
            "attribution": {
                "title": attribution
            },
            "infoFormats": [
                "text/plain", "application/vnd.ogc.gml", "text/xml",
                "application/vnd.ogc.gml/3.1.1", "text/xml; subtype=gml/3.1.1",
                "text/html", "application/json"
            ],
            "styles": [sld_definition(s) for s in layer.styles.all()],
            "prefix":
            layer.alternate.split(":")[0] if ":" in layer.alternate else "",
            "keywords":
            [k.name for k in layer.keywords.all()] if layer.keywords else [],
            "llbbox":
            decimal_encode(bbox) if layer.srid == 'EPSG:4326' else
            bbox_to_projection([float(coord) for coord in layer_bbox] + [
                layer.srid,
            ],
                               target_srid=4326)[:4]
        }

        all_times = None
        if check_ogc_backend(geoserver.BACKEND_PACKAGE):
            if layer.has_time:
                from geonode.geoserver.views import get_capabilities
                workspace, layername = layer.alternate.split(
                    ":") if ":" in layer.alternate else (None, layer.alternate)
                # WARNING Please make sure to have enabled DJANGO CACHE as per
                # https://docs.djangoproject.com/en/2.0/topics/cache/#filesystem-caching
                wms_capabilities_resp = get_capabilities(request,
                                                         layer.id,
                                                         tolerant=True)
                if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400:
                    wms_capabilities = wms_capabilities_resp.getvalue()
                    if wms_capabilities:
                        from defusedxml import lxml as dlxml
                        namespaces = {
                            'wms': 'http://www.opengis.net/wms',
                            'xlink': 'http://www.w3.org/1999/xlink',
                            'xsi': 'http://www.w3.org/2001/XMLSchema-instance'
                        }
                        e = dlxml.fromstring(wms_capabilities)
                        for atype in e.findall(
                                "./[wms:Name='%s']/wms:Dimension[@name='time']"
                                % (layer.alternate), namespaces):
                            dim_name = atype.get('name')
                            if dim_name:
                                dim_name = str(dim_name).lower()
                                if dim_name == 'time':
                                    dim_values = atype.text
                                    if dim_values:
                                        all_times = dim_values.split(",")
                                        break
                if all_times:
                    config["capability"]["dimensions"] = {
                        "time": {
                            "name": "time",
                            "units": "ISO8601",
                            "unitsymbol": None,
                            "nearestVal": False,
                            "multipleVal": False,
                            "current": False,
                            "default": "current",
                            "values": all_times
                        }
                    }

        if layer.storeType == "remoteStore":
            service = layer.remote_service
            source_params = {}
            if service.type in ('REST_MAP', 'REST_IMG'):
                source_params = {
                    "ptype": service.ptype,
                    "remote": True,
                    "url": service.service_url,
                    "name": service.name,
                    "title": "[R] %s" % service.title
                }
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps(source_params))
        else:
            ogc_server_url = urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlsplit(layer.ows_url).netloc

            access_token = request.session[
                'access_token'] if request and 'access_token' in request.session else None
            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = '%s?access_token=%s' % (layer.ows_url, access_token)
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True)

        layers.append(maplayer)

    if bbox and len(bbox) >= 4:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(request, *layers_to_add)

    config['fromLayer'] = True
    return config
Beispiel #23
0
def map_embed_widget(request, mapid,
                     template='leaflet/maps/map_embed_widget.html'):
    """Display code snippet for embedding widget.

    :param request: The request from the frontend.
    :type request: HttpRequest

    :param mapid: The id of the map.
    :type mapid: String

    :return: formatted code.
    """
    map_obj = _resolve_map(request,
                           mapid,
                           'base.view_resourcebase',
                           _PERMISSION_MSG_VIEW)
    map_bbox = map_obj.bbox_string.split(',')

    # Sanity Checks
    for coord in map_bbox:
        if not coord:
            return

    map_layers = MapLayer.objects.filter(
        map_id=mapid).order_by('stack_order')
    layers = []
    for layer in map_layers:
        if layer.group != 'background':
            layers.append(layer)

    if map_obj.srid != 'EPSG:3857':
        map_bbox = [float(coord) for coord in map_bbox]
    else:
        map_bbox = llbbox_to_mercator([float(coord) for coord in map_bbox])

    if map_bbox and len(map_bbox) >= 4:
        minx, miny, maxx, maxy = [float(coord) for coord in map_bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(settings, 'DEFAULT_MAP_CRS') == "EPSG:3857":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    context = {
        'resource': map_obj,
        'map_bbox': map_bbox,
        'map_layers': layers
    }
    message = render(request, template, context)
    return HttpResponse(message)
Beispiel #24
0
def add_layers_to_map_config(
        request, map_obj, layer_names, add_base_layers=True):
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

    bbox = []
    layers = []
    for layer_name in layer_names:
        try:
            layer = _resolve_layer(request, layer_name)
        except ObjectDoesNotExist:
            # bad layer, skip
            continue
        except Http404:
            # can't find the layer, skip it.
            continue

        if not request.user.has_perm(
                'view_resourcebase',
                obj=layer.get_self_resource()):
            # invisible layer, skip inclusion
            continue

        layer_bbox = layer.bbox[0:4]
        bbox = layer_bbox[:]
        bbox[0] = layer_bbox[0]
        bbox[1] = layer_bbox[2]
        bbox[2] = layer_bbox[1]
        bbox[3] = layer_bbox[3]
        # assert False, str(layer_bbox)

        def decimal_encode(bbox):
            import decimal
            _bbox = []
            for o in [float(coord) for coord in bbox]:
                if isinstance(o, decimal.Decimal):
                    o = (str(o) for o in [o])
                _bbox.append(o)
            # Must be in the form : [x0, x1, y0, y1
            return [_bbox[0], _bbox[2], _bbox[1], _bbox[3]]

        def sld_definition(style):
            from urllib import quote
            _sld = {
                "title": style.sld_title or style.name,
                "legend": {
                    "height": "40",
                    "width": "22",
                    "href": layer.ows_url +
                    "?service=wms&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=" +
                    quote(layer.service_typename, safe=''),
                    "format": "image/png"
                },
                "name": style.name
            }
            return _sld

        config = layer.attribute_config()
        if hasattr(layer, 'srid'):
            config['crs'] = {
                'type': 'name',
                'properties': layer.srid
            }
        # Add required parameters for GXP lazy-loading
        attribution = "%s %s" % (layer.owner.first_name,
                                 layer.owner.last_name) if layer.owner.first_name or layer.owner.last_name else str(
            layer.owner)
        srs = getattr(settings, 'DEFAULT_MAP_CRS', 'EPSG:3857')
        srs_srid = int(srs.split(":")[1]) if srs != "EPSG:900913" else 3857
        config["attribution"] = "<span class='gx-attribution-title'>%s</span>" % attribution
        config["format"] = getattr(
            settings, 'DEFAULT_LAYER_FORMAT', 'image/png')
        config["title"] = layer.title
        config["wrapDateLine"] = True
        config["visibility"] = True
        config["srs"] = srs
        config["bbox"] = decimal_encode(
            bbox_to_projection([float(coord) for coord in layer_bbox] + [layer.srid, ],
                               target_srid=int(srs.split(":")[1]))[:4])
        config["capability"] = {
            "abstract": layer.abstract,
            "name": layer.alternate,
            "title": layer.title,
            "queryable": True,
            "storeType": layer.storeType,
            "bbox": {
                layer.srid: {
                    "srs": layer.srid,
                    "bbox": decimal_encode(bbox)
                },
                srs: {
                    "srs": srs,
                    "bbox": decimal_encode(
                        bbox_to_projection([float(coord) for coord in layer_bbox] + [layer.srid, ],
                                           target_srid=srs_srid)[:4])
                },
                "EPSG:4326": {
                    "srs": "EPSG:4326",
                    "bbox": decimal_encode(bbox) if layer.srid == 'EPSG:4326' else
                    decimal_encode(bbox_to_projection(
                        [float(coord) for coord in layer_bbox] + [layer.srid, ], target_srid=4326)[:4])
                },
                "EPSG:900913": {
                    "srs": "EPSG:900913",
                    "bbox": decimal_encode(bbox) if layer.srid == 'EPSG:900913' else
                    decimal_encode(bbox_to_projection(
                        [float(coord) for coord in layer_bbox] + [layer.srid, ], target_srid=3857)[:4])
                }
            },
            "srs": {
                srs: True
            },
            "formats": ["image/png", "application/atom xml", "application/atom+xml", "application/json;type=utfgrid",
                        "application/openlayers", "application/pdf", "application/rss xml", "application/rss+xml",
                        "application/vnd.google-earth.kml", "application/vnd.google-earth.kml xml",
                        "application/vnd.google-earth.kml+xml", "application/vnd.google-earth.kml+xml;mode=networklink",
                        "application/vnd.google-earth.kmz", "application/vnd.google-earth.kmz xml",
                        "application/vnd.google-earth.kmz+xml", "application/vnd.google-earth.kmz;mode=networklink",
                        "atom", "image/geotiff", "image/geotiff8", "image/gif", "image/gif;subtype=animated",
                        "image/jpeg", "image/png8", "image/png; mode=8bit", "image/svg", "image/svg xml",
                        "image/svg+xml", "image/tiff", "image/tiff8", "image/vnd.jpeg-png",
                        "kml", "kmz", "openlayers", "rss", "text/html; subtype=openlayers", "utfgrid"],
            "attribution": {
                "title": attribution
            },
            "infoFormats": ["text/plain", "application/vnd.ogc.gml", "text/xml", "application/vnd.ogc.gml/3.1.1",
                            "text/xml; subtype=gml/3.1.1", "text/html", "application/json"],
            "styles": [sld_definition(s) for s in layer.styles.all()],
            "prefix": layer.alternate.split(":")[0] if ":" in layer.alternate else "",
            "keywords": [k.name for k in layer.keywords.all()] if layer.keywords else [],
            "llbbox": decimal_encode(bbox) if layer.srid == 'EPSG:4326' else
            decimal_encode(bbox_to_projection(
                [float(coord) for coord in layer_bbox] + [layer.srid, ], target_srid=4326)[:4])
        }

        all_times = None
        if check_ogc_backend(geoserver.BACKEND_PACKAGE):
            from geonode.geoserver.views import get_capabilities
            workspace, layername = layer.alternate.split(
                ":") if ":" in layer.alternate else (None, layer.alternate)
            # WARNING Please make sure to have enabled DJANGO CACHE as per
            # https://docs.djangoproject.com/en/2.0/topics/cache/#filesystem-caching
            wms_capabilities_resp = get_capabilities(
                request, layer.id, tolerant=True)
            if wms_capabilities_resp.status_code >= 200 and wms_capabilities_resp.status_code < 400:
                wms_capabilities = wms_capabilities_resp.getvalue()
                if wms_capabilities:
                    import xml.etree.ElementTree as ET
                    namespaces = {'wms': 'http://www.opengis.net/wms',
                                  'xlink': 'http://www.w3.org/1999/xlink',
                                  'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}

                    e = ET.fromstring(wms_capabilities)
                    for atype in e.findall(
                            "./[wms:Name='%s']/wms:Dimension[@name='time']" % (layer.alternate), namespaces):
                        dim_name = atype.get('name')
                        if dim_name:
                            dim_name = str(dim_name).lower()
                            if dim_name == 'time':
                                dim_values = atype.text
                                if dim_values:
                                    all_times = dim_values.split(",")
                                    break
            if all_times:
                config["capability"]["dimensions"] = {
                    "time": {
                        "name": "time",
                        "units": "ISO8601",
                        "unitsymbol": None,
                        "nearestVal": False,
                        "multipleVal": False,
                        "current": False,
                        "default": "current",
                        "values": all_times
                    }
                }

        if layer.storeType == "remoteStore":
            service = layer.remote_service
            source_params = {}
            if service.type in ('REST_MAP', 'REST_IMG'):
                source_params = {
                    "ptype": service.ptype,
                    "remote": True,
                    "url": service.service_url,
                    "name": service.name,
                    "title": "[R] %s" % service.title}
            maplayer = MapLayer(map=map_obj,
                                name=layer.alternate,
                                ows_url=layer.ows_url,
                                layer_params=json.dumps(config),
                                visibility=True,
                                source_params=json.dumps(source_params)
            )
        else:
            ogc_server_url = urlparse.urlsplit(
                ogc_server_settings.PUBLIC_LOCATION).netloc
            layer_url = urlparse.urlsplit(layer.ows_url).netloc

            access_token = request.session['access_token'] if request and 'access_token' in request.session else None
            if access_token and ogc_server_url == layer_url and 'access_token' not in layer.ows_url:
                url = '%s?access_token=%s' % (layer.ows_url, access_token)
            else:
                url = layer.ows_url
            maplayer = MapLayer(
                map=map_obj,
                name=layer.alternate,
                ows_url=url,
                # use DjangoJSONEncoder to handle Decimal values
                layer_params=json.dumps(config, cls=DjangoJSONEncoder),
                visibility=True
            )

        layers.append(maplayer)

    if bbox and len(bbox) >= 4:
        minx, maxx, miny, maxy = [float(coord) for coord in bbox]
        x = (minx + maxx) / 2
        y = (miny + maxy) / 2

        if getattr(
            settings,
            'DEFAULT_MAP_CRS',
                'EPSG:3857') == "EPSG:4326":
            center = list((x, y))
        else:
            center = list(forward_mercator((x, y)))

        if center[1] == float('-inf'):
            center[1] = 0

        BBOX_DIFFERENCE_THRESHOLD = 1e-5

        # Check if the bbox is invalid
        valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
        valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

        if valid_x:
            width_zoom = math.log(360 / abs(maxx - minx), 2)
        else:
            width_zoom = 15

        if valid_y:
            height_zoom = math.log(360 / abs(maxy - miny), 2)
        else:
            height_zoom = 15

        map_obj.center_x = center[0]
        map_obj.center_y = center[1]
        map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

    map_obj.handle_moderated_uploads()

    if add_base_layers:
        layers_to_add = DEFAULT_BASE_LAYERS + layers
    else:
        layers_to_add = layers
    config = map_obj.viewer_json(
        request, *layers_to_add)

    config['fromLayer'] = True
    return config
    def get_context_data(self, **kwargs):
        request = self.request
        if request and 'access_token' in request.session:
            access_token = request.session['access_token']
        else:
            access_token = None

        DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

        layers = Layer.objects.all()

        if request.method == 'GET' and 'copy' in request.GET:
            """Prepare context data."""
            request = self.request
            mapid = self.request.GET['copy']

            map_obj = _resolve_map(request, mapid, 'base.view_resourcebase',
                                   _PERMISSION_MSG_VIEW)

            config = map_obj.viewer_json(request)

            # list all required layers
            map_layers = MapLayer.objects.filter(
                map_id=mapid).order_by('stack_order')
            context = {
                'config':
                json.dumps(config),
                'create':
                False,
                'layers':
                layers,
                'map':
                map_obj,
                'map_layers':
                map_layers,
                'preview':
                getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
                        'leaflet')
            }
            return context
        else:
            if request.method == 'GET':
                params = request.GET
            elif request.method == 'POST':
                params = request.POST
            else:
                return self.render_to_response(status=405)

            if 'layer' in params:
                bbox = None
                map_obj = Map(projection=getattr(settings, 'DEFAULT_MAP_CRS',
                                                 'EPSG:3857'))

                for layer_name in params.getlist('layer'):
                    try:
                        layer = _resolve_layer(request, layer_name)
                    except ObjectDoesNotExist:
                        # bad layer, skip
                        continue

                    if not request.user.has_perm(
                            'view_resourcebase',
                            obj=layer.get_self_resource()):
                        # invisible layer, skip inclusion
                        continue

                    layer_bbox = layer.bbox
                    # assert False, str(layer_bbox)
                    if bbox is None:
                        bbox = list(layer_bbox[0:4])
                    else:
                        bbox[0] = min(bbox[0], layer_bbox[0])
                        bbox[1] = min(bbox[1], layer_bbox[1])
                        bbox[2] = max(bbox[2], layer_bbox[2])
                        bbox[3] = max(bbox[3], layer_bbox[3])

                    config = layer.attribute_config()

                    # Add required parameters for GXP lazy-loading
                    config["title"] = layer.title
                    config["queryable"] = True

                    config["srs"] = getattr(settings, 'DEFAULT_MAP_CRS',
                                            'EPSG:3857')
                    config["bbox"] = bbox if config["srs"] != 'EPSG:3857' \
                        else llbbox_to_mercator(
                        [float(coord) for coord in bbox])

                    if layer.storeType == "remoteStore":
                        service = layer.remote_service
                        # Probably not a good idea to send the access token to every remote service.
                        # This should never match, so no access token should be sent to remote services.
                        ogc_server_url = urlsplit(
                            ogc_server_settings.PUBLIC_LOCATION).netloc
                        service_url = urlsplit(service.base_url).netloc

                        if access_token and ogc_server_url == service_url and \
                                'access_token' not in service.base_url:
                            url = '%s?access_token=%s' % (service.base_url,
                                                          access_token)
                        else:
                            url = service.base_url
                        map_layers = MapLayer(map=map_obj,
                                              name=layer.typename,
                                              ows_url=layer.ows_url,
                                              layer_params=json.dumps(config),
                                              visibility=True,
                                              source_params=json.dumps({
                                                  "ptype":
                                                  service.ptype,
                                                  "remote":
                                                  True,
                                                  "url":
                                                  url,
                                                  "name":
                                                  service.name,
                                                  "title":
                                                  "[R] %s" % service.title
                                              }))
                    else:
                        ogc_server_url = urlsplit(
                            ogc_server_settings.PUBLIC_LOCATION).netloc
                        layer_url = urlsplit(layer.ows_url).netloc

                        if access_token and ogc_server_url == layer_url and \
                                'access_token' not in layer.ows_url:
                            url = layer.ows_url + '?access_token=' + \
                                access_token
                        else:
                            url = layer.ows_url
                        map_layers = MapLayer(
                            map=map_obj,
                            name=layer.typename,
                            ows_url=url,
                            # use DjangoJSONEncoder to handle Decimal values
                            layer_params=json.dumps(config,
                                                    cls=DjangoJSONEncoder),
                            visibility=True)

                if bbox and len(bbox) >= 4:
                    minx, miny, maxx, maxy = [float(coord) for coord in bbox]
                    x = (minx + maxx) / 2
                    y = (miny + maxy) / 2

                    if getattr(settings, 'DEFAULT_MAP_CRS',
                               'EPSG:3857') == "EPSG:4326":
                        center = list((x, y))
                    else:
                        center = list(forward_mercator((x, y)))

                    if center[1] == float('-inf'):
                        center[1] = 0

                    BBOX_DIFFERENCE_THRESHOLD = 1e-5

                    # Check if the bbox is invalid
                    valid_x = (maxx - minx)**2 > BBOX_DIFFERENCE_THRESHOLD
                    valid_y = (maxy - miny)**2 > BBOX_DIFFERENCE_THRESHOLD

                    if valid_x:
                        width_zoom = math.log(360 / abs(maxx - minx), 2)
                    else:
                        width_zoom = 15

                    if valid_y:
                        height_zoom = math.log(360 / abs(maxy - miny), 2)
                    else:
                        height_zoom = 15

                    map_obj.center_x = center[0]
                    map_obj.center_y = center[1]
                    map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

                map_obj.handle_moderated_uploads()

                config = map_obj.viewer_json(request)
                config['fromLayer'] = True
                context = {
                    'config':
                    json.dumps(config),
                    'create':
                    True,
                    'layers':
                    layers,
                    'map':
                    map_obj,
                    'map_layers':
                    map_layers,
                    'preview':
                    getattr(settings, 'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
                            'leaflet')
                }

            else:
                # list all required layers
                layers = Layer.objects.all()
                context = {'create': True, 'layers': layers}
            return context
Beispiel #26
0
def get_bbox(instance, crs='EPSG:3857'):
    if crs is None:
        crs = 'EPSG:3857'
    minlon = min(float(instance.bbox_x0), float(instance.bbox_x1))
    minlat = min(float(instance.bbox_y0), float(instance.bbox_y1))
    maxlon = max(float(instance.bbox_x0), float(instance.bbox_x1))
    maxlat = max(float(instance.bbox_y0), float(instance.bbox_y1))

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    # create a buffer
    minlon = max(-180, minlon - lon_range * .1)
    minlat = max(-90, minlat - lat_range * .1)
    maxlon = min(180, maxlon + lon_range * .1)
    maxlat = min(90, maxlat + lat_range * .1)

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    if ratio < 200.0 / 150.0:
        lon_shift = abs(.5 * ((200.0 / 150.0 * lat_range) - lon_range))
        minlon = max(-180, minlon - lon_shift)
        maxlon = min(180, maxlon + lon_shift)
    else:
        adjusted_range = 150.0 / 200.0 * lon_range
        range_delta = adjusted_range - lat_range
        lat_shift = abs(.5 * range_delta)
        minlat = max(-90, minlat - lat_shift)
        maxlat = min(90, maxlat + lat_shift)

    lon_range = maxlon - minlon
    lat_range = maxlat - minlat
    ratio = lon_range / lat_range

    height = int(200 / ratio)
    logger.debug('height: %s', height)

    if crs == 'EPSG:3857':
        # create bbox in 3857
        minx, miny = forward_mercator([minlon, max(-85.0, minlat)])
        maxx, maxy = forward_mercator([maxlon, min(85.0, maxlat)])
        bbox = '%s,%s,%s,%s' % (
            minx,
            miny,
            maxx,
            maxy
        )
        return bbox, height
    elif crs == 'EPSG:4326':
        # deal with weird bbox order for geographic coords in wms 1.3.0
        bbox = '%s,%s,%s,%s' % (
            minlat,
            minlon,
            maxlat,
            maxlon
        )
        return bbox, height
    elif crs == 'CRS:84':
        # crs84 bbox
        bbox = '%s,%s,%s,%s' % (
            minlon,
            minlat,
            maxlon,
            maxlat
        )
        return bbox, height
    logger.debug('***************Could not determine BBOX***********')
Beispiel #27
0
def new_map_config(request):
    '''
    View that creates a new map.

    If the query argument 'copy' is given, the initial map is
    a copy of the map with the id specified, otherwise the
    default map configuration is used.  If copy is specified
    and the map specified does not exist a 404 is returned.
    '''
    DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config()

    if request.method == 'GET' and 'copy' in request.GET:
        mapid = request.GET['copy']
        map_obj = _resolve_map(request, mapid, 'base.view_resourcebase')

        map_obj.abstract = DEFAULT_ABSTRACT
        map_obj.title = DEFAULT_TITLE
        if request.user.is_authenticated():
            map_obj.owner = request.user
        config = map_obj.viewer_json(request.user)
        del config['id']
    else:
        if request.method == 'GET':
            params = request.GET
        elif request.method == 'POST':
            params = request.POST
        else:
            return HttpResponse(status=405)

        if 'layer' in params:
            bbox = None
            map_obj = Map(projection="EPSG:900913")
            layers = []
            for layer_name in params.getlist('layer'):
                try:
                    layer = _resolve_layer(request, layer_name)
                except ObjectDoesNotExist:
                    # bad layer, skip
                    continue

                if not request.user.has_perm(
                        'view_resourcebase',
                        obj=layer.get_self_resource()):
                    # invisible layer, skip inclusion
                    continue

                layer_bbox = layer.bbox
                # assert False, str(layer_bbox)
                if bbox is None:
                    bbox = list(layer_bbox[0:4])
                else:
                    bbox[0] = min(bbox[0], layer_bbox[0])
                    bbox[1] = max(bbox[1], layer_bbox[1])
                    bbox[2] = min(bbox[2], layer_bbox[2])
                    bbox[3] = max(bbox[3], layer_bbox[3])

                config = layer.attribute_config()

                # Add required parameters for GXP lazy-loading
                config["srs"] = layer.srid
                config["title"] = layer.title
                config["bbox"] = [
                    float(coord) for coord in bbox] if layer.srid == "EPSG:4326" else llbbox_to_mercator(
                    [
                        float(coord) for coord in bbox])
                config["queryable"] = True

                if layer.storeType == "remoteStore":
                    service = layer.service
                    maplayer = MapLayer(map=map_obj,
                                        name=layer.typename,
                                        ows_url=layer.ows_url,
                                        layer_params=json.dumps(config),
                                        visibility=True,
                                        source_params=json.dumps({
                                            "ptype": service.ptype,
                                            "remote": True,
                                            "url": service.base_url,
                                            "name": service.name}))
                else:
                    maplayer = MapLayer(
                        map=map_obj,
                        name=layer.typename,
                        ows_url=layer.ows_url,
                        layer_params=json.dumps(config),
                        visibility=True
                    )

                layers.append(maplayer)

            if bbox is not None:
                minx, miny, maxx, maxy = [float(c) for c in bbox]
                x = (minx + maxx) / 2
                y = (miny + maxy) / 2

                center = list(forward_mercator((x, y)))
                if center[1] == float('-inf'):
                    center[1] = 0

                BBOX_DIFFERENCE_THRESHOLD = 1e-5

                # Check if the bbox is invalid
                valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
                valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

                if valid_x:
                    width_zoom = math.log(360 / abs(maxx - minx), 2)
                else:
                    width_zoom = 15

                if valid_y:
                    height_zoom = math.log(360 / abs(maxy - miny), 2)
                else:
                    height_zoom = 15

                map_obj.center_x = center[0]
                map_obj.center_y = center[1]
                map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

            config = map_obj.viewer_json(
                request.user, *(DEFAULT_BASE_LAYERS + layers))
            config['fromLayer'] = True
        else:
            config = DEFAULT_MAP_CONFIG
    return json.dumps(config)
Beispiel #28
0
    def get_context_data(self, **kwargs):
        request = self.request
        if request and 'access_token' in request.session:
            access_token = request.session['access_token']
        else:
            access_token = None

        snapshot = self.kwargs.get('snapshot')

        DEFAULT_MAP_CONFIG, DEFAULT_BASE_LAYERS = default_map_config(request)

        layers = Layer.objects.all()

        if request.method == 'GET' and 'copy' in request.GET:
            """Prepare context data."""
            request = self.request
            mapid = self.request.GET['copy']

            map_obj = _resolve_map(
                request, mapid, 'base.view_resourcebase', _PERMISSION_MSG_VIEW)

            if snapshot is None:
                config = map_obj.viewer_json(request)
            else:
                config = snapshot_config(snapshot, map_obj, request)
            # list all required layers
            map_layers = MapLayer.objects.filter(
                map_id=mapid).order_by('stack_order')
            context = {
                'config': json.dumps(config),
                'create': False,
                'layers': layers,
                'map': map_obj,
                'map_layers': map_layers,
                'preview': getattr(
                    settings,
                    'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
                    '')
            }
            return context
        else:
            if request.method == 'GET':
                params = request.GET
            elif request.method == 'POST':
                params = request.POST
            else:
                return self.render_to_response(status=405)

            if 'layer' in params:
                bbox = None
                map_obj = Map(projection=getattr(
                    settings, 'DEFAULT_MAP_CRS', 'EPSG:3857'))

                for layer_name in params.getlist('layer'):
                    try:
                        layer = _resolve_layer(request, layer_name)
                    except ObjectDoesNotExist:
                        # bad layer, skip
                        continue

                    if not request.user.has_perm(
                            'view_resourcebase',
                            obj=layer.get_self_resource()):
                        # invisible layer, skip inclusion
                        continue

                    layer_bbox = layer.bbox
                    # assert False, str(layer_bbox)
                    if bbox is None:
                        bbox = list(layer_bbox[0:4])
                    else:
                        bbox[0] = min(bbox[0], layer_bbox[0])
                        bbox[1] = min(bbox[1], layer_bbox[1])
                        bbox[2] = max(bbox[2], layer_bbox[2])
                        bbox[3] = max(bbox[3], layer_bbox[3])

                    config = layer.attribute_config()

                    # Add required parameters for GXP lazy-loading
                    config["title"] = layer.title
                    config["queryable"] = True

                    config["srs"] = getattr(settings,
                                            'DEFAULT_MAP_CRS', 'EPSG:3857')
                    config["bbox"] = bbox if config["srs"] != 'EPSG:3857' \
                        else llbbox_to_mercator(
                        [float(coord) for coord in bbox])

                    if layer.storeType == "remoteStore":
                        service = layer.remote_service
                        # Probably not a good idea to send the access token to every remote service.
                        # This should never match, so no access token should be sent to remote services.
                        ogc_server_url = urlparse.urlsplit(
                            ogc_server_settings.PUBLIC_LOCATION).netloc
                        service_url = urlparse.urlsplit(
                            service.base_url).netloc

                        if access_token and ogc_server_url == service_url and \
                                'access_token' not in service.base_url:
                            url = '%s?access_token=%s' % (service.base_url, access_token)
                        else:
                            url = service.base_url
                        map_layers = MapLayer(map=map_obj,
                                              name=layer.typename,
                                              ows_url=layer.ows_url,
                                              layer_params=json.dumps(config),
                                              visibility=True,
                                              source_params=json.dumps({
                                                "ptype": service.ptype,
                                                "remote": True,
                                                "url": url,
                                                "name": service.name,
                                                "title": "[R] %s" % service.title}))
                    else:
                        ogc_server_url = urlparse.urlsplit(
                            ogc_server_settings.PUBLIC_LOCATION).netloc
                        layer_url = urlparse.urlsplit(layer.ows_url).netloc

                        if access_token and ogc_server_url == layer_url and \
                                'access_token' not in layer.ows_url:
                            url = layer.ows_url + '?access_token=' + \
                                  access_token
                        else:
                            url = layer.ows_url
                        map_layers = MapLayer(
                            map=map_obj,
                            name=layer.typename,
                            ows_url=url,
                            # use DjangoJSONEncoder to handle Decimal values
                            layer_params=json.dumps(
                                config,
                                cls=DjangoJSONEncoder),
                            visibility=True
                        )

                if bbox and len(bbox) >= 4:
                    minx, miny, maxx, maxy = [float(coord) for coord in bbox]
                    x = (minx + maxx) / 2
                    y = (miny + maxy) / 2

                    if getattr(settings,
                               'DEFAULT_MAP_CRS', 'EPSG:3857') == "EPSG:4326":
                        center = list((x, y))
                    else:
                        center = list(forward_mercator((x, y)))

                    if center[1] == float('-inf'):
                        center[1] = 0

                    BBOX_DIFFERENCE_THRESHOLD = 1e-5

                    # Check if the bbox is invalid
                    valid_x = (maxx - minx) ** 2 > BBOX_DIFFERENCE_THRESHOLD
                    valid_y = (maxy - miny) ** 2 > BBOX_DIFFERENCE_THRESHOLD

                    if valid_x:
                        width_zoom = math.log(360 / abs(maxx - minx), 2)
                    else:
                        width_zoom = 15

                    if valid_y:
                        height_zoom = math.log(360 / abs(maxy - miny), 2)
                    else:
                        height_zoom = 15

                    map_obj.center_x = center[0]
                    map_obj.center_y = center[1]
                    map_obj.zoom = math.ceil(min(width_zoom, height_zoom))

                map_obj.handle_moderated_uploads()

                if snapshot is None:
                    config = map_obj.viewer_json(request)
                else:
                    config = snapshot_config(snapshot, map_obj, request)

                config['fromLayer'] = True
                context = {
                    'config': json.dumps(config),
                    'create': True,
                    'layers': layers,
                    'map': map_obj,
                    'map_layers': map_layers,
                    'preview': getattr(
                        settings,
                        'GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY',
                        '')
                }

            else:
                # list all required layers
                layers = Layer.objects.all()
                context = {
                    'create': True,
                    'layers': layers
                }
            return context