Пример #1
0
    def connect(self, coverage, data_items, layer, options):
        path = join("/vsimem", uuid4().hex)
        range_type = coverage.range_type
        num_bands = len(coverage.range_type)

        vrt_builder = vrt.VRTBuilder(coverage.size_x, coverage.size_y, vrt_filename=path)

        bands_re = re.compile(r"bands\[(\d+)(,\d+)?\]")

        for data_item in sorted(data_items, key=lambda d: d.semantic):
            start, end = bands_re.match(data_item.semantic).groups()
            start = int(start)
            end = int(end) if end is not None else None
            if end is None:
                dst_band_indices = range(start + 1, start + 2)
                src_band_indices = range(1, 2)
            else:
                dst_band_indices = range(start + 1, end + 2)
                src_band_indices = range(1, end - start + 1)

            for src_index, dst_index in zip(src_band_indices, dst_band_indices):
                vrt_builder.add_band(range_type[dst_index - 1].data_type)
                vrt_builder.add_simple_source(
                    dst_index,
                    # gdal.OpenShared(data_item.location),
                    data_item.location,
                    src_index,
                )

        print data_items[0].location
        print gdal.OpenShared(data_items[0].location).GetGCPs()
        if isinstance(coverage, models.ReferenceableDataset):
            vrt_builder.copy_gcps(gdal.OpenShared(data_items[0].location))
            layer.setMetaData("eoxs_ref_data", path)

        layer.data = path

        # with vsi.open(path, "w+") as f:
        #    print type(vrt_builder.build())
        #    f.write(vrt_builder.build())

        del vrt_builder
        with vsi.open(path) as f:
            print f.read(100000)

        # layer.clearProcessing()
        # layer.addProcessing("SCALE_1=1,4")
        # layer.addProcessing("BANDS=2")
        # layer.offsite = mapserver.colorObj(0,0,0)

        if isinstance(coverage, models.ReferenceableDataset):
            vrt_path = join("/vsimem", uuid4().hex)
            reftools.create_rectified_vrt(path, vrt_path)
            layer.data = vrt_path
            layer.setMetaData("eoxs_ref_data", path)

            with vsi.open(vrt_path) as f:
                print f.read(100000)

        """
Пример #2
0
    def encode(self, request, collection_id, queryset, search_context):
        """ Encode a query set as an OGR datasource and retrieve its contents.
        """
        # create a datasource and its fields
        driver = self.get_driver()
        filename = self.get_filename()
        ds = self.create_datasource(driver, filename)
        layer = self.create_layer(ds)
        self.create_fields(layer)
        definition = layer.GetLayerDefn()

        # encode the objects
        for eo_object in queryset:
            feature = self.create_feature(layer, definition)
            self.set_feature_values(feature, eo_object)
            layer.CreateFeature(feature)

        # close datasource and read contents
        ds.Destroy()

        with vsi.open(filename) as f:
            content = f.read()

        # perform cleanup and return content + mimetype
        self.cleanup(driver, ds, filename)
        return content
Пример #3
0
    def connect(self, coverage, data_items, layer):

        # TODO: implement
        vrt_doc = vrt.VRT()
        # TODO: configure vrt here

        path = join("/vsimem", uuid4().hex)
        with vsi.open(path, "w+") as f:
            vrt_doc.write(f)


        # TODO!!
        if layer.metadata.get("eoxs_wrap_dateline") == "true":
            e = wrap_extent_around_dateline(coverage.extent, coverage.srid)

            vrt_path = join("/vsimem", uuid4().hex)
            ds = gdal.Open(data)
            vrt_ds = create_simple_vrt(ds, vrt_path)
            size_x = ds.RasterXSize
            size_y = ds.RasterYSize
            
            dx = abs(e[0] - e[2]) / size_x
            dy = abs(e[1] - e[3]) / size_y 
            
            vrt_ds.SetGeoTransform([e[0], dx, 0, e[3], 0, -dy])
            vrt_ds = None
            
            layer.data = vrt_path

        layer.data = path
Пример #4
0
    def encode(self, request, collection_id, queryset, search_context):
        """ Encode a query set as an OGR datasource and retrieve its contents.
        """
        # create a datasource and its fields
        driver = self.get_driver()
        filename = self.get_filename()
        ds = self.create_datasource(driver, filename)
        layer = self.create_layer(ds)
        self.create_fields(layer)
        definition = layer.GetLayerDefn()

        # encode the objects
        for eo_object in queryset:
            feature = self.create_feature(layer, definition)
            self.set_feature_values(feature, eo_object)
            layer.CreateFeature(feature)

        # close datasource and read contents
        ds.Destroy()

        with vsi.open(filename) as f:
            content = f.read()

        # perform cleanup and return content + mimetype
        self.cleanup(driver, ds, filename)
        return content
Пример #5
0
    def encode_eo_metadata(self, coverage, request=None, subset_polygon=None):
        metadata_items = [
            metadata_location for metadata_location in getattr(
                coverage, 'metadata_locations', [])
            if metadata_location.format == "eogml"
        ]
        if len(metadata_items) >= 1:
            with vsi.open(metadata_items[0].path) as f:
                earth_observation = etree.parse(f).getroot()

            if subset_polygon:
                try:
                    feature = earth_observation.xpath("om:featureOfInterest",
                                                      namespaces=nsmap)[0]
                    feature[0] = self.encode_footprint(
                        coverage.footprint.intersection(subset_polygon),
                        coverage.identifier)
                except IndexError:
                    pass  # no featureOfInterest

        else:
            earth_observation = self.encode_earth_observation(
                coverage.identifier,
                coverage.begin_time,
                coverage.end_time,
                coverage.footprint,
                subset_polygon=subset_polygon)

        if not request:
            lineage = None

        elif request.method == "GET":
            lineage = EOWCS(
                "lineage",
                EOWCS(
                    "referenceGetCoverage",
                    self.encode_reference(
                        "Reference",
                        request.build_absolute_uri().replace("&", "&"),
                        False)), GML("timePosition", isoformat(now())))
        elif request.method == "POST":  # TODO: better way to do this
            href = request.build_absolute_uri().replace("&", "&")
            lineage = EOWCS(
                "lineage",
                EOWCS(
                    "referenceGetCoverage",
                    OWS("ServiceReference",
                        OWS("RequestMessage",
                            etree.parse(request).getroot()),
                        **{ns_xlink("href"): href})),
                GML("timePosition", isoformat(now())))

        return GMLCOV(
            "metadata",
            GMLCOV(
                "Extension",
                EOWCS("EOMetadata", earth_observation,
                      *[lineage] if lineage is not None else [])))
Пример #6
0
    def connect(self, coverage, data_items, layer, options):
        path = join("/vsimem", uuid4().hex)
        range_type = coverage.range_type

        # size_x, size_y = coverage.size[:2]
        # vrt_builder = vrt.VRTBuilder(size_x, size_y, vrt_filename=path)

        # for data_item in data_items:
        #     start = data_item.start_field
        #     end = data_item.end_field
        #     if end is None:
        #         dst_band_indices = range(start+1, start+2)
        #         src_band_indices = range(1, 2)
        #     else:
        #         dst_band_indices = range(start+1, end+2)
        #         src_band_indices = range(1, end-start+1)

        #     for src_index, dst_index in zip(src_band_indices, dst_band_indices):
        #         vrt_builder.add_band(range_type[dst_index-1].data_type)
        #         vrt_builder.add_simple_source(
        #             dst_index,
        #             data_item.path,
        #             src_index
        #         )

        # if coverage.grid.is_referenceable:
        #     vrt_builder.copy_gcps(gdal.OpenShared(data_items[0].path))
        #     layer.setMetaData("eoxs_ref_data", path)

        # layer.data = path

        # del vrt_builder

        # with vsi.open(path) as f:
        #     print f.read(100000)

        vrt.gdalbuildvrt(
            path, [location.path for location in coverage.arraydata_locations],
            separate=True)

        layer.data = path

        #layer.clearProcessing()
        #layer.addProcessing("SCALE_1=1,4")
        #layer.addProcessing("BANDS=2")
        #layer.offsite = mapserver.colorObj(0,0,0)

        if coverage.grid.is_referenceable:
            vrt_path = join("/vsimem", uuid4().hex)
            reftools.create_rectified_vrt(path, vrt_path)
            layer.data = vrt_path
            layer.setMetaData("eoxs_ref_data", path)

            with vsi.open(vrt_path) as f:
                print(f.read(100000))
        """
Пример #7
0
def gdalbuildvrt(filename, paths, separate=False, nodata=None):
    """ Builds a VRT file from the passed files using the
        `gdalbuildvrt` command and stores the resulting file
        under the passed filename.
    """
    args = [
        '/usr/bin/gdalbuildvrt',
        '-resolution',
        'highest',
        '-q',
        '/vsistdout/',
    ]
    if separate:
        args.append('-separate')

    if nodata is not None:
        args.extend(['-srcnodata', ' '.join(str(value) for value in nodata)])

    content = subprocess.check_output(args + paths)

    with vsi.open(filename, "w") as f:
        f.write(content)
Пример #8
0
def create_rectified_vrt(path_or_ds,
                         vrt_path,
                         srid_or_wkt=None,
                         resample=0,
                         memory_limit=0.0,
                         max_error=APPROX_ERR_TOL,
                         method=METHOD_GCP,
                         order=0,
                         size=None,
                         resolution=None):
    """ Creates a VRT dataset that symbolizes a rectified version of the
    passed "referenceable" GDAL dataset.

    :param path_or_ds: a :class:`GDAL Dataset <eoxserver.contrib.gdal.Dataset>`
                       or a path to such
    :param vrt_path: the path to store the VRT dataset under

    :param resample: the resample method to be used; defaults to 0 which means
                     a nearest neighbour resampling
    :param memory_limit: the memory limit; by default no limit is used
    :param max_error: the maximum allowed error
    :param method: either of :const:`METHOD_GCP`, :const:`METHOD_TPS` or
                   :const:`METHOD_TPS_LSQ`.
    :param order: the order of the function; see :func:`get_footprint_wkt` for
                  reference
    """

    if size and resolution:
        raise ValueError('size and resolution ar mutually exclusive')

    ds = _open_ds(path_or_ds)
    ptr = C.c_void_p(int(ds.this))

    if isinstance(srid_or_wkt, int):
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(srid_or_wkt)
        wkt = srs.ExportToWkt()
        srs = None
    elif isinstance(srid_or_wkt, str):
        wkt = srid_or_wkt
    else:
        wkt = ds.GetGCPProjection()

    # transformer = _create_generic_transformer(
    #     ds, None, None, wkt, method, order
    # )

    # x_size = C.c_int()
    # y_size = C.c_int()
    # geotransform = (C.c_double * 6)()

    # GDALSuggestedWarpOutput(
    #     ptr,
    #     GDALGenImgProjTransform, transformer, geotransform,
    #     C.byref(x_size), C.byref(y_size)
    # )

    # GDALSetGenImgProjTransformerDstGeoTransform(transformer, geotransform)

    # options = GDALCreateWarpOptions()
    # options.dfWarpMemoryLimit = memory_limit
    # options.eResampleAlg = resample
    # options.pfnTransformer = GDALGenImgProjTransform
    # options.pTransformerArg = transformer
    # options.hDstDS = C.c_void_p(int(ds.this))

    # nb = options.nBandCount = ds.RasterCount

    # src_bands = C.cast(CPLMalloc(C.sizeof(C.c_int) * nb), C.POINTER(C.c_int))
    # dst_bands = C.cast(CPLMalloc(C.sizeof(C.c_int) * nb), C.POINTER(C.c_int))

    # # ctypes.cast(x, ctypes.POINTER(ctypes.c_ulong))

    # options.panSrcBands = src_bands
    # options.panDstBands = dst_bands

    # # TODO: nodata value setup
    # for i in xrange(nb):
    #     options.panSrcBands[i] = i + 1
    #     options.panDstBands[i] = i + 1

    # if max_error > 0:
    #     GDALApproxTransform = _libgdal.GDALApproxTransform

    #     options.pTransformerArg = GDALCreateApproxTransformer(
    #         options.pfnTransformer, options.pTransformerArg, max_error
    #     )
    #     options.pfnTransformer = GDALApproxTransform
    # TODO: correct for python
    #GDALApproxTransformerOwnsSubtransformer(options.pTransformerArg, False)

    # if size:
    #     extent = _to_extent(x_size.value, y_size.value, geotransform)
    #     size_x, size_y = size
    #     x_size.value = size_x
    #     y_size.value = size_y
    #     geotransform = _to_gt(size[0], size[1], extent)

    # elif resolution:
    #     extent = _to_extent(x_size.value, y_size.value, geotransform)

    #     geotransform[1] = resolution[0]
    #     geotransform[5] = resolution[1]

    #     size_x, size_y = _to_size(geotransform, extent)
    #     x_size.value = size_x
    #     y_size.value = size_y

    # vrt_ds = GDALCreateWarpedVRT(ptr, x_size, y_size, geotransform, options)
    if isinstance(wkt, str):
        wkt = b(wkt)
    vrt_ds = GDALAutoCreateWarpedVRT(ptr, None, wkt, resample, max_error, None)
    # GDALSetProjection(vrt_ds, wkt)
    if isinstance(vrt_path, str):
        vrt_path = b(vrt_path)

    GDALSetDescription(vrt_ds, vrt_path)
    GDALClose(vrt_ds)
    # GDALDestroyWarpOptions(options)

    # if size of resolution is overridden parse the VRT and adjust settings
    if size or resolution:
        with vsi.open(vrt_path) as f:
            root = parse(f).getroot()

        size_x = int(root.attrib['rasterXSize'])
        size_y = int(root.attrib['rasterYSize'])
        gt_elem = root.find('GeoTransform')

        gt = [
            float(value.strip()) for value in gt_elem.text.strip().split(',')
        ]

        if size:
            extent = _to_extent(size_x, size_y, gt)
            size_x, size_y = size
            gt = _to_gt(size[0], size[1], extent)

        elif resolution:
            extent = _to_extent(size_x, size_y, gt)

            gt[1] = resolution[0]
            gt[5] = resolution[1]

            size_x, size_y = _to_size(gt, extent)

        # Adjust XML
        root.attrib['rasterXSize'] = str(size_x)
        root.attrib['rasterYSize'] = str(size_y)

        gt_str = ",".join(str(v) for v in gt)
        gt_elem.text = gt_str
        root.find('GDALWarpOptions/Transformer/ApproxTransformer/'
                  'BaseTransformer/GenImgProjTransformer/DstGeoTransform'
                  ).text = gt_str

        inv_gt = gdal.InvGeoTransform(gt)
        root.find('GDALWarpOptions/Transformer/ApproxTransformer/'
                  'BaseTransformer/GenImgProjTransformer/DstInvGeoTransform'
                  ).text = ",".join(str(v) for v in inv_gt)

        # write XML back to file
        with vsi.open(vrt_path, "w") as f:
            f.write(etree.tostring(root, pretty_print=True))
Пример #9
0
    def render_map(self, render_map):
        # TODO: get layer creators for each layer type in the map
        map_obj = ms.mapObj()

        if render_map.bgcolor:
            map_obj.imagecolor.setHex("#" + render_map.bgcolor.lower())
        else:
            map_obj.imagecolor.setRGB(0, 0, 0)

        frmt = getFormatRegistry().getFormatByMIME(render_map.format)

        if not frmt:
            raise MapRenderError('No such format %r' % render_map.format,
                                 code='InvalidFormat',
                                 locator='format')

        outputformat_obj = ms.outputFormatObj(frmt.driver)

        outputformat_obj.transparent = (ms.MS_ON if render_map.transparent else
                                        ms.MS_OFF)
        outputformat_obj.mimetype = frmt.mimeType

        if frmt.defaultExt:
            if frmt.defaultExt.startswith('.'):
                extension = frmt.defaultExt[1:]
            else:
                extension = frmt.defaultExt

            outputformat_obj.extension = extension

        map_obj.setOutputFormat(outputformat_obj)

        #
        map_obj.setExtent(*render_map.bbox)
        map_obj.setSize(render_map.width, render_map.height)
        map_obj.setProjection(render_map.crs)
        map_obj.setConfigOption('MS_NONSQUARE', 'yes')

        layers_plus_factories = self._get_layers_plus_factories(render_map)
        layers_plus_factories_plus_data = [
            (layer, factory, factory.create(map_obj, layer))
            for layer, factory in layers_plus_factories
        ]

        # log the resulting map
        if logger.isEnabledFor(logging.DEBUG):
            with tempfile.NamedTemporaryFile() as f:
                map_obj.save(f.name)
                f.seek(0)
                logger.debug(f.read().decode('ascii'))

        try:
            # actually render the map
            image_obj = map_obj.draw()

            try:
                image_bytes = image_obj.getBytes()
            except Exception:
                tmp_name = '/vsimem/%s' % uuid4().hex
                image_obj.save(tmp_name, map_obj)
                with vsi.open(tmp_name) as f:
                    image_bytes = f.read()
                vsi.unlink(tmp_name)

            extension = outputformat_obj.extension
            if extension:
                if len(render_map.layers) == 1:
                    filename = '%s.%s' % (render_map.layers[0].name, extension)
                else:
                    filename = 'map.%s' % extension
            else:
                filename = None

            return image_bytes, outputformat_obj.mimetype, filename

        finally:
            # disconnect
            for layer, factory, data in layers_plus_factories_plus_data:
                factory.destroy(map_obj, layer, data)
Пример #10
0
    def connect(self, coverage, data_items, layer, options):
        path = join("/vsimem", uuid4().hex)
        range_type = coverage.range_type
        num_bands = len(coverage.range_type)

        vrt_builder = vrt.VRTBuilder(coverage.size_x,
                                     coverage.size_y,
                                     vrt_filename=path)

        bands_re = re.compile(r"bands\[(\d+)(,\d+)?\]")

        for data_item in sorted(data_items, key=lambda d: d.semantic):
            start, end = bands_re.match(data_item.semantic).groups()
            start = int(start)
            end = int(end) if end is not None else None
            if end is None:
                dst_band_indices = range(start + 1, start + 2)
                src_band_indices = range(1, 2)
            else:
                dst_band_indices = range(start + 1, end + 2)
                src_band_indices = range(1, end - start + 1)

            for src_index, dst_index in zip(src_band_indices,
                                            dst_band_indices):
                vrt_builder.add_band(range_type[dst_index - 1].data_type)
                vrt_builder.add_simple_source(
                    dst_index,
                    #gdal.OpenShared(data_item.location),
                    data_item.location,
                    src_index)

        print data_items[0].location
        print gdal.OpenShared(data_items[0].location).GetGCPs()
        if isinstance(coverage, models.ReferenceableDataset):
            vrt_builder.copy_gcps(gdal.OpenShared(data_items[0].location))
            layer.setMetaData("eoxs_ref_data", path)

        layer.data = path

        #with vsi.open(path, "w+") as f:
        #    print type(vrt_builder.build())
        #    f.write(vrt_builder.build())

        del vrt_builder
        with vsi.open(path) as f:
            print f.read(100000)

        #layer.clearProcessing()
        #layer.addProcessing("SCALE_1=1,4")
        #layer.addProcessing("BANDS=2")
        #layer.offsite = mapserver.colorObj(0,0,0)

        if isinstance(coverage, models.ReferenceableDataset):
            vrt_path = join("/vsimem", uuid4().hex)
            reftools.create_rectified_vrt(path, vrt_path)
            layer.data = vrt_path
            layer.setMetaData("eoxs_ref_data", path)

            with vsi.open(vrt_path) as f:
                print f.read(100000)
        """