Example #1
0
    def get_layer_points_wfs(self, layer, bbox, max_features):

        # Get points in bbox by creating/dispatching an WFS GetFeature
        # internally. This is a nice abstraction from various source types like
        # PostGIS, Shape etc.
        wfs_req = mapscript.OWSRequest()
        wfs_req.setParameter("SERVICE", "WFS")
        wfs_req.setParameter("VERSION", "1.1.0")
        wfs_req.setParameter("REQUEST", "GetFeature")
        wfs_req.setParameter("TYPENAME", layer)
        wfs_req.setParameter("BBOX", bbox)
        wfs_req.setParameter("VERSION", "1.1.0")
        #    wfs_req.setParameter( 'SRSNAME', "EPSG:4326")  ?????

        # TODO: reproject response points

        mapscript.msIO_installStdoutToBuffer()

        self.map.OWSDispatch(wfs_req)
        #    print 'bbox=' + wms_req.getValueByName('BBOX')
        mapscript.msIO_stripStdoutBufferContentType()
        content = mapscript.msIO_getStdoutBufferString()

        # Parse WFS result into array of Point (slooow, TODO optimize)
        parser = WFSParser(mapscript.msGetVersionInt() >= 50600, max_features)

        return parser.parse(content)
Example #2
0
def wms(request):
    import mapscript
    image = None
    for field in ['IMAGE', 'COVERAGE', 'image', 'coverage', 'id', 'ID']:
        if field in request.GET: image = request.GET[field] 
    try:
        image = int(image)
        obj = Map.objects.get(pk=image)
        filename = obj.warped
    except:
        filename = "%s" % image 
    filename = "%s/%s" % (settings.MAP_PATH, os.path.basename(filename))    
    ows = mapscript.OWSRequest()
    for k, v in request.GET.items():
        if k.lower() in ['image', 'coverage']: continue 
        ows.setParameter(k, v)
    ows.setParameter("LAYERS", "image")
    ows.setParameter("COVERAGE", "image")
    map = mapscript.mapObj('%s/wms.map' % settings.BASE_PATH)
    raster = mapscript.layerObj(map)
    raster.name = 'image'
    raster.type = mapscript.MS_LAYER_RASTER
    raster.data = filename 
    raster.status = mapscript.MS_DEFAULT
    raster.setProjection( "+init=epsg:4326" )
    raster.dump = mapscript.MS_TRUE
    raster.metadata.set("wcs_formats", "GEOTIFF JPEG2000")
    mapscript.msIO_installStdoutToBuffer()
    contents = map.OWSDispatch(ows)
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    return HttpResponse(content, content_type = content_type)
Example #3
0
def mapserver_wms(map_name, layer_id, client_rev):
    wrapper = instances.get_or_create(map_name, layer_id)
    if wrapper is None:
        abort(404)
    # load in request parameters
    req = mapscript.OWSRequest()
    for (k, v) in request.args.iteritems():
        if k == 'LAYERS':
            v = ','.join((t.name for t in wrapper.layers))
        req.setParameter(k, v)
    # shared stdio buffer object thing; make sure that there's nothing left over
    # from an aborted request stuck in there
    mapscript.msIO_getStdoutBufferBytes()
    try:
        wrapper.instance.OWSDispatch(req)
        headers = {'Cache-Control': 'max-age=86400, public'}
    except mapscript.MapServerError:
        # don't cache errors
        headers = {}
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    return Response(headers=headers,
                    response=content,
                    status=200,
                    content_type=content_type)
def application(env, start_response):
    for key in MAPSERV_ENV:
        if key in env:
            os.environ[key] = env[key]
        else:
            os.unsetenv(key)

    # Using a statically assigned mapfile:
    filename = os.path.join(settings_local['base_path'], 'test_mapfile.map')
    mapfile = mapscript.mapObj(filename)

    req = mapscript.OWSRequest()
    mapscript.msIO_installStdoutToBuffer()

    req.loadParamsFromURL(env['QUERY_STRING'])
    set_default_parameters(req)

    try:
        status = mapfile.OWSDispatch(req)
    except Exception as err:
        pass

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    result = mapscript.msIO_getStdoutBufferBytes()
    start_response('200 OK', [('Content-type', content_type)])
    return [result]
Example #5
0
def mapserver(params,mapfile):
    """ Function implementing mapserver functionality.
    
    params: dictionary of query string of a mapserver GET request
    mapfile: path to mapfile
    
    returns: tuple with content type and response body
    """
    helper.dbg("creating map for: " + mapfile)
    request = mapscript.OWSRequest()
    #request.loadParams()
    for k in params:
        #helper.dbg( "%s : %s" % (k,params[k]))
        request.setParameter(k,params[k])
    # change the style INSPIRE:DEFAULT back to an empty string otherwise Mapserver will complain
    styles = request.getValueByName('STYLES')
    if (styles is not None and styles.count(default_style) > 0):
        styles = styles.replace(default_style, "")
        request.setParameter("STYLES", styles)
    style = request.getValueByName('STYLE')
    if style == default_style:
        request.setParameter("STYLE", "") 
            
    map = mapscript.mapObj( mapfile )
    mapscript.msIO_installStdoutToBuffer()
    map.OWSDispatch( request )
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    operation = request.getValueByName('REQUEST')
    version = request.getValueByName('VERSION')
    if (version == '1.3.0' or version is None) and operation.upper() == 'GETCAPABILITIES':
        content = altercapabilities(content, namespace, prefix, schemaLocation, language)
    #response = 'Content-type: %s\n%s' % (content_type,content)    
    return [content_type, content]
Example #6
0
def wms(request):
    import mapscript
    image = None
    for field in ['IMAGE', 'COVERAGE', 'image', 'coverage', 'id', 'ID']:
        if field in request.GET: image = request.GET[field]
    try:
        image = int(image)
        obj = Map.objects.get(pk=image)
        filename = obj.warped
    except:
        filename = "%s" % image
    filename = "%s/%s" % (settings.MAP_PATH, os.path.basename(filename))
    ows = mapscript.OWSRequest()
    for k, v in request.GET.items():
        if k.lower() in ['image', 'coverage']: continue
        ows.setParameter(k, v)
    ows.setParameter("LAYERS", "image")
    ows.setParameter("COVERAGE", "image")
    map = mapscript.mapObj('%s/wms.map' % settings.BASE_PATH)
    raster = mapscript.layerObj(map)
    raster.name = 'image'
    raster.type = mapscript.MS_LAYER_RASTER
    raster.data = filename
    raster.status = mapscript.MS_DEFAULT
    raster.setProjection("+init=epsg:4326")
    raster.dump = mapscript.MS_TRUE
    mapscript.msIO_installStdoutToBuffer()
    contents = map.OWSDispatch(ows)
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    return HttpResponse(content, content_type=content_type)
Example #7
0
def main(map_file):

    map = mapscript.mapObj(map_file)
    map.setMetaData("ows_onlineresource", "http://dummy.org/")
    ows_req = mapscript.OWSRequest()

    ows_req.type = mapscript.MS_GET_REQUEST

    ows_req.setParameter("SERVICE", "WMS")
    ows_req.setParameter("VERSION", "1.1.0")
    ows_req.setParameter("REQUEST", "GetCapabilities")

    mapscript.msIO_installStdoutToBuffer()
    dispatch_status = map.OWSDispatch(ows_req)

    if dispatch_status != mapscript.MS_SUCCESS:
        print("An error occurred")

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    mapscript.msIO_stripStdoutBufferContentHeaders()
    result = mapscript.msIO_getStdoutBufferBytes()

    # [('Content-Type', 'application/vnd.ogc.wms_xml; charset=UTF-8'), ('Content-Length', '11385')]
    response_headers = [('Content-Type', content_type),
                        ('Content-Length', str(len(result)))]

    assert int(response_headers[1][1]) > 0

    dom = xml.dom.minidom.parseString(result)
    print(dom.toprettyxml(indent="", newl=""))
Example #8
0
def main(map_file):

    map = mapscript.mapObj(map_file)
    map.web.metadata.set("ows_onlineresource", "http://dummy.org/")
    ows_req = mapscript.OWSRequest()

    ows_req.type = mapscript.MS_GET_REQUEST

    ows_req.setParameter("SERVICE", "WMS")
    ows_req.setParameter("VERSION", "1.1.0")
    ows_req.setParameter("REQUEST", "GetCapabilities")

    mapscript.msIO_installStdoutToBuffer()
    dispatch_status = map.OWSDispatch(ows_req)

    if dispatch_status != mapscript.MS_SUCCESS:
        print("An error occurred")

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    mapscript.msIO_stripStdoutBufferContentHeaders()
    result = mapscript.msIO_getStdoutBufferBytes()

    # [('Content-Type', 'application/vnd.ogc.wms_xml; charset=UTF-8'), ('Content-Length', '11385')]
    response_headers = [('Content-Type', content_type),
                        ('Content-Length', str(len(result)))]

    assert int(response_headers[1][1]) > 0

    dom = xml.dom.minidom.parseString(result)
    print(dom.toprettyxml(indent="", newl=""))
def application(env, start_response):
    print "-" * 30
    for key in MAPSERV_ENV:
        if key in env:
            os.environ[key] = env[key]
            print "{0}='{1}'".format(key, env[key])
        else:
            os.unsetenv(key)
    print "-" * 30

    #mapfile = '/home/oldbay/GIS/mapserver/basemaps/build/basemaps/osm-google-fix.map'
    #mapfile = 'temp_debug.map'
    #mapfile = mapscript.mapObj(mapfile)

    mapfile = initMap()

    request = mapscript.OWSRequest()
    mapscript.msIO_installStdoutToBuffer()
    request.loadParamsFromURL(env['QUERY_STRING'])

    try:
        status = mapfile.OWSDispatch(request)
    except Exception as err:
        pass

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    result = mapscript.msIO_getStdoutBufferBytes()
    start_response('200 OK', [('Content-type', content_type)])
    return [result]
Example #10
0
def get_wms_response(query_string, base_url, out_format, layers):
    group = 'raster_layers'
    layer_names = []
    for layer in layers:
        name = layer.get('name')
        if name:
            layer_names.append(name)
    req = get_wms_request(query_string=query_string, layer_names=layer_names)
    src_map = get_map(base_url=base_url,
                      out_format=out_format,
                      layers=layers,
                      group=group)
    # raise ValueError(src_map.outputformat.imagemode, mapscript.MS_IMAGEMODE_INT16)
    mapscript.msIO_installStdoutToBuffer()
    try:
        src_map.OWSDispatch(req)
        error = False
    except mapscript.MapServerError:
        error = True
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    mapscript.msIO_resetHandlers()

    # if content_type == 'vnd.ogc.se_xml':
    #     content_type = 'text/xml'
    return content, content_type, error
    def render(self):
        """ Render this map object

            This will inspect the OWS request type, and render the correct image
            for the request.

            Known supported OWS REQUEST values:

            * GetLegendGraphic: Will render the legend for the OWS request
            * GetMap: Will render the map tile for the OWS request
        """

        log = logging.getLogger(__name__)

        content = None          # the bytes of the rendered image
        content_type = None     # the image mimetype
        retval = None           # the OWS return value, useful for debugging

        with self.__class__.MAPSCRIPT_RLOCK:
            try:
                ows_request_type = self.ows_request.getValueByName('REQUEST')

                if (ows_request_type == 'GetLegendGraphic'):
                    # Draw the legend for the map
                    retval = self.loadOWSParameters(self.ows_request)
                    image = self.drawLegend()
                    content = image.getBytes()
                    content_type = image.format.mimetype
                elif (ows_request_type == 'GetMap'):
                    # Draw the map (tiles)
                    retval = self.loadOWSParameters(self.ows_request)
                    image = self.draw()
                    content = image.getBytes()
                    content_type = image.format.mimetype
                else:
                    # Unexpected OWS request. Do our best to support it by
                    # falling back to using the OWS Dispatch

                    # Tell mapscript to start capturing the stdout in a buffer
                    mapscript.msIO_installStdoutToBuffer()
                    # dispatch the OWS request
                    retval = self.OWSDispatch(self.ows_request)
                    # Get the content type of the return value
                    content_type = mapscript.msIO_stripStdoutBufferContentType()
                    # Get the content of the resulting image
                    content = mapscript.msIO_getStdoutBufferBytes()

                if retval != mapscript.MS_SUCCESS:
                    # Failed to render the desired image
                    raise RuntimeError("Failed to render map OWS request")

            except:
                log.error("Error while trying to render map: %s", sys.exc_info()[0])
                raise
            finally:
                # Reset the mapscript I/O pointers back to where they should be
                mapscript.msIO_resetHandlers()

        return content, content_type, retval
    def application(self, env, start_response):
        q_str = {
            my.split("=")[0].upper(): my.split("=")[1]
            for my in env['QUERY_STRING'].split('&') if "=" in my
        }
        serv_ver = [q_str.get('SERVICE', False), q_str.get('VERSION', False)]

        print "-" * 30
        for key in self.MAPSERV_ENV:
            if key in env:
                os.environ[key] = env[key]
                print "{0}='{1}'".format(key, env[key])
            else:
                os.unsetenv(key)
        print "QUERY_STRING=("
        for key in q_str:
            print "    {0}={1},".format(key, q_str[key])
        print ")"
        print "-" * 30

        request = mapscript.OWSRequest()
        mapscript.msIO_installStdoutToBuffer()
        request.loadParamsFromURL(env['QUERY_STRING'])
        rec_obj = self.mapscript_obj.clone()

        try:
            status_id = rec_obj.OWSDispatch(request)
        except Exception as err:
            print "OWSDispatch Error: {}".format(err)
            err_def = unicode(err).split(':')[0]
            status_id = None

        content_type = mapscript.msIO_stripStdoutBufferContentType()
        result = mapscript.msIO_getStdoutBufferBytes()
        mapscript.msIO_resetHandlers()

        # status:
        if status_id == mapscript.MS_SUCCESS:
            status = '200 OK'
        elif status_id == mapscript.MS_FAILURE:
            status = '400 Bad request'
            if serv_ver == ['WFS', '2.0.0']:
                result = '\n'.join(result.split('\n')[2:])
        elif status_id is None:
            if serv_ver[0] == "WMS" and err_def == "msPostGISLayerGetExtent()":
                status = '200 OK'
            elif serv_ver == ['WFS', '1.0.0'
                              ] and err_def == "msWFSGetFeature()":
                status = '400 Bad request'
            else:
                status = '500 Server Error'

        start_response(status, [('Content-type', str(content_type))])
        return [result]
Example #13
0
 def request_mapscript(self, env, mapdata, que=None):
     """
     render on mapserver mapscript request
     """
     q_str = {
         my.split("=")[0].upper(): my.split("=")[1]
         for my 
         in env['QUERY_STRING'].split('&')
         if "=" in my
     }
     serv_ver = [q_str.get('SERVICE', False), q_str.get('VERSION', False)]
     request = mapscript.OWSRequest()
     mapscript.msIO_installStdoutToBuffer()
     request.loadParamsFromURL(env['QUERY_STRING'])
     rec_obj = mapdata.clone()
 
     try:
         status_id = rec_obj.OWSDispatch(request)
     except Exception as err:
         print "OWSDispatch Error: {}".format(err)
         err_def = unicode(err).split(':')[0]
         status_id = None
 
     content_type = mapscript.msIO_stripStdoutBufferContentType()
     content = mapscript.msIO_getStdoutBufferBytes()
     mapscript.msIO_resetHandlers()
     
     # status:
     if status_id == mapscript.MS_SUCCESS:
         status = 200
     elif status_id == mapscript.MS_FAILURE:
         status = 400
         if serv_ver == ['WFS', '2.0.0']:
             content = '\n'.join(content.split('\n')[2:])
     elif status_id is None:
         if serv_ver[0] == "WMS" and err_def == "msPostGISLayerGetExtent()":
             status = 200
         elif serv_ver == ['WFS', '1.0.0'] and err_def == "msWFSGetFeature()":
             status = 400
         else:
             status = 500
     else:
         status = 500
     
     out_response = (
         status, 
         content_type, 
         content
     )
     if que is None:
         return out_response
     else:
         que.put(out_response)
Example #14
0
    def ows_req(self):
        # http://mapserver.org/ogc/mapscript.html#python-examples
        ows_req = mapscript.OWSRequest()
        ows_req.loadParams()
        req_str = ows_req.getValueByName("REQUEST")
        styles = ows_req.getValueByName("STYLES")

        do_heatmap = styles and styles.startswith("heat")

        # Filter out "graphic" WMS requests
        if req_str == "GetMap" and do_heatmap:
            self.wms_getheatmap_req(ows_req)
            return
        elif req_str == "GetLegendGraphic":
            # GetLegendGraphic may have a optional STYLE parameter
            # if this indicates a heatmap style defer to our own implementation
            # to return heatmap gradient image as style for now.
            style = ows_req.getValueByName("STYLE")
            if style and style.startswith("heat"):
                self.wms_getheatmaplegend_req(ows_req)
                return

        # All other OWS (WFS/WMS-non-graphic) are XML-based
        # and can be dispatched/returned directly
        ows_req.setParameter("STYLES", "")
        mapscript.msIO_installStdoutToBuffer()
        self.map.OWSDispatch(ows_req)

        if req_str == "GetMap":
            content = mapscript.msIO_getStdoutBufferBytes()
        else:
            content_type = mapscript.msIO_stripStdoutBufferContentType()
            content = mapscript.msIO_getStdoutBufferString()

            if (
                content_type == "vnd.ogc.se_xml"
                or content_type == "application/vnd.ogc.wms_xml"
                or content_type == "application/vnd.ogc.gml"
            ):
                content_type = "text/xml"

            print("Content-type: " + content_type)
            print

        print(content)
def wxs():
    import mapscript
    import os
    path_map = os.path.join(request.folder, 'private', request.args(0))
    if not request.vars:
        return ''
    req = mapscript.OWSRequest()
    for v in request.vars:
        req.setParameter(v, request.vars[v])

    map = mapscript.mapObj(path_map)
    mapscript.msIO_installStdoutToBuffer()
    map.OWSDispatch(req)

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    response.header = "Content-Type","%s; charset=utf-8"%content_type
    return content
def wxs():
    import mapscript
    import os
    path_map = os.path.join(request.folder, 'private', request.args(0))
    if not request.vars:
        return ''
    req = mapscript.OWSRequest()
    for v in request.vars:
        req.setParameter(v, request.vars[v])

    map = mapscript.mapObj(path_map)
    mapscript.msIO_installStdoutToBuffer()
    map.OWSDispatch(req)

    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    response.header = "Content-Type", "%s; charset=utf-8" % content_type
    return content
Example #17
0
    def request_mapscript(self, env, mapdata, que=None):
        """
        render on mapserver mapscript request
        """
        request = mapscript.OWSRequest()
        mapscript.msIO_installStdoutToBuffer()
        request.loadParamsFromURL(env['QUERY_STRING'])

        try:
            status = mapdata.OWSDispatch(request)
        except Exception as err:
            pass

        content_type = mapscript.msIO_stripStdoutBufferContentType()
        result = mapscript.msIO_getStdoutBufferBytes()
        out_req = (content_type, result)
        if que is None:
            return out_req
        else:
            que.put(out_req)
Example #18
0
def application(environ, start_response):
    try:
        req = mapscript.OWSRequest()
        req.loadParamsFromURL(environ.get('QUERY_STRING'))

        map = mapscript.mapObj(args.map_file)

        mapscript.msIO_installStdoutToBuffer()
        map.OWSDispatch(req)

        content_type = mapscript.msIO_stripStdoutBufferContentType()
        content = mapscript.msIO_getStdoutBufferBytes()

        if content_type == 'vnd.ogc.se_xml':
            content_type = 'text/xml'

        start_response('200 Ok', [('Content-type', content_type)])
        return [content]

    except:
        start_response('500 Ooops', [('Content-type', 'text/plain')])
        return ['An error occured\n' + mapscript.msIO_getStdoutBufferString()]
Example #19
0
def mapserver_wms(map_name, layer_id, client_rev):
    wrapper = instances.get_or_create(map_name, layer_id)
    if wrapper is None:
        abort(404)
    # load in request parameters
    req = mapscript.OWSRequest()
    for (k, v) in request.args.iteritems():
        if k == 'LAYERS':
            v = ','.join((t.name for t in wrapper.layers))
        req.setParameter(k, v)
    # shared stdio buffer object thing; make sure that there's nothing left over
    # from an aborted request stuck in there
    mapscript.msIO_getStdoutBufferBytes()
    try:
        wrapper.instance.OWSDispatch(req)
        headers = {'Cache-Control' : 'max-age=86400, public'}
    except mapscript.MapServerError:
        # don't cache errors
        headers = {}
    content_type = mapscript.msIO_stripStdoutBufferContentType()
    content = mapscript.msIO_getStdoutBufferBytes()
    return Response(headers=headers, response=content, status=200, content_type=content_type)
Example #20
0
def process_request(django_request, map_obj):
    """Offload the processing of the OWS request to MapServer.

    :arg django_request: the request parameters
    :type django_request: HttpRequest
    :arg map_obj: the in-memory mapfile to use
    :type map_obj: mapscript.mapObj
    :return: the mapserver buffer with the output from processing the request
    """

    if django_request.method == 'GET':
        params = django_request.GET
    elif django_request.method == 'POST':
        # get the params from the XML body of the request
        raise Exception
    # build the WMS request
    wms_req = mapscript.OWSRequest()
    for k, v in params.items():
        wms_req.setParameter(k, v)

    # install a mapserver IO handler directing future stdout to a memory buffer
    output_buffer = mapscript.msIO_installStdoutToBuffer()

    # dispatch the request to mapserver
    map_obj.OWSDispatch(wms_req)

    # get back mapserver's response
    # ms_headers = mapscript.msIO_stripStdoutBufferContentHeaders()
    ms_content_type = mapscript.msIO_stripStdoutBufferContentType()
    ms_content = mapscript.msIO_getStdoutBufferBytes()
    if ms_content == 'application/vnd.ogc.se_xml':
        ms_content = 'Content-Type: text/xml\n\n{}'.format(ms_content)

    # reset the stdin/stdout handlers
    mapscript.msIO_resetHandlers()
    return ms_content, ms_content_type
Example #21
0
    def application(self, env, start_response):
        print "-" * 30
        for key in self.MAPSERV_ENV:
            if key in env:
                os.environ[key] = env[key]
                print "{0}='{1}'".format(key, env[key])
            else:
                os.unsetenv(key)
        print "-" * 30

        mapfile = self.get_mapobj()
        request = mapscript.OWSRequest()
        mapscript.msIO_installStdoutToBuffer()
        request.loadParamsFromURL(env['QUERY_STRING'])

        try:
            status = mapfile.OWSDispatch(request)
        except Exception as err:
            pass

        content_type = mapscript.msIO_stripStdoutBufferContentType()
        result = mapscript.msIO_getStdoutBufferBytes()
        start_response('200 OK', [('Content-type', content_type)])
        return [result]
Example #22
0
map = mapscript.mapObj('../../tests/test.map')
map.setMetaData("ows_onlineresource", "http://dummy.org/")
ows_req = mapscript.OWSRequest()

ows_req.type = mapscript.MS_GET_REQUEST

ows_req.setParameter("SERVICE", "WMS")
ows_req.setParameter("VERSION", "1.1.0")
ows_req.setParameter("REQUEST", "GetCapabilities")

mapscript.msIO_installStdoutToBuffer()
dispatch_status = map.OWSDispatch(ows_req)
if dispatch_status:
    status = '200 OK'
else:
    status = '500 Internal Server Error'
content_type = mapscript.msIO_stripStdoutBufferContentType()
mapscript.msIO_stripStdoutBufferContentHeaders()
result = mapscript.msIO_getStdoutBufferBytes()

try:
    # MapServer 6.0:
    mapscript.msCleanup()
except:
    # MapServer 6.1:
    mapscript.msCleanup(1)

response_headers = [('Content-Type', content_type),
                    ('Content-Length', str(len(result)))]
    def test_get_productlayer(self):
        #import StringIO
        import mapscript
        # getparams = web.input()

        #getparams = {'STYLES': u'', 'productcode': u'vgt-ndvi', 'legendid': u'7', 'SERVICE': u'WMS', 'subproductcode': u'ndv', 'CRS': u'EPSG:4326', 'FORMAT': u'image/png', 'REQUEST': u'GetMap', 'HEIGHT': u'1010', 'WIDTH': u'998', 'VERSION': u'1.3.0', 'productversion': u'sv2-pv2.1', 'date': u'20130221', 'mapsetcode': u'SPOTV-Africa-1km', 'TRANSPARENT': u'false', 'BBOX': u'-16.17,16.17,-15.47,16.87'}
        getparams = {'STYLES': u'',
                     'productcode': u'vgt-fapar',
                     'legendid': u'99',
                     'SERVICE': u'WMS',
                     'subproductcode': u'fapar',
                     'CRS': u'EPSG:4326',
                     'FORMAT': u'image/png',
                     'REQUEST': u'GetMap',
                     'HEIGHT': u'1010',
                     'WIDTH': u'998',
                     'VERSION': u'1.3.0',
                     'productversion': u'V1.4',
                     'date': u'20130221',
                     'mapsetcode': u'SPOTV-Africa-1km',
                     'TRANSPARENT': u'false',
                     'BBOX': u'15.46875, -17.578125, 16.171875, -16.875'}

        #getparams = {'STYLES': u'', 'productcode': u'vgt-ndvi', 'legendid': u'7', 'SERVICE': u'WMS', 'subproductcode': u'ndv', 'CRS': u'EPSG:4326', 'FORMAT': u'image/png', 'REQUEST': u'GetMap', 'HEIGHT': u'1091', 'WIDTH': u'998', 'VERSION': u'1.3.0', 'productversion': u'sv2-pv2.1', 'date': u'20130221', 'mapsetcode': u'SPOTV-Africa-1km', 'TRANSPARENT': u'false', 'BBOX': u'-25.70957541665903,9.276714800828785,-13.723491432284028,20.021343707078785'}
        # getparams = [
        #     SERVICE:'WMS',
        #     VERSION='1.3.0',
        #     REQUEST='GetMap',
        #     FORMAT='image/png',
        #     TRANSPARENT='false',
        #     productcode='vgt-ndvi',
        #     productversion='sv2-pv2.1',
        #     subproductcode='ndv',
        #     mapsetcode='SPOTV-Africa-1km',
        #     legendid='7',
        #     date='20130221',
        #     CRS='EPSG:4326'',
        #     STYLES=''
        #     WIDTH='998',
        #     HEIGHT='1010',
        #     BBOX='-26,-35,60,38'
        # ]
        p = Product(product_code=getparams['productcode'], version=getparams['productversion'])
        dataset = p.get_dataset(mapset=getparams['mapsetcode'], sub_product_code=getparams['subproductcode'])
        # print dataset.fullpath

        if hasattr(getparams, "date"):
            filedate = getparams['date']
        else:
            dataset.get_filenames()
            lastdate = dataset.get_dates()[-1].strftime("%Y%m%d")
            filedate = lastdate

        if dataset.no_year():
            filedate=dataset.strip_year(filedate)
        # lastdate = lastdate.replace("-", "")
        # mydate=lastdate.strftime("%Y%m%d")

        filename = functions.set_path_filename(filedate,
                                               getparams['productcode'],
                                               getparams['subproductcode'],
                                               getparams['mapsetcode'],
                                               getparams['productversion'],
                                               '.tif')
        productfile = dataset.fullpath + filename
        # print productfile

        #web.header('Content-type', 'image/png')
        #web.header('Content-transfer-encoding', 'binary')
        #buf = StringIO.StringIO()
        #mapscript.msIO_installStdoutToBuffer()
        #map = mapserver.getmap()
        ##map.save to a file fname.png
        ##web.header('Content-Disposition', 'attachment; filename="fname.png"')
        #contents = buf.getvalue()
        #return contents

        #logger.debug("MapServer: Installing stdout to buffer.")
        mapscript.msIO_installStdoutToBuffer()

        # projlib = "/usr/share/proj/"
        projlib = es_constants.proj4_lib_dir
        # errorfile = es_constants.apps_dir+"/analysis/ms_tmp/ms_errors.log"
        errorfile = es_constants.log_dir+"/mapserver_error.log"
        # imagepath = es_constants.apps_dir+"/analysis/ms_tmp/"

        owsrequest = mapscript.OWSRequest()

        inputparams = getparams # web.input()
        for k, v in inputparams.iteritems():
            print k + ':' + v
            owsrequest.setParameter(k.upper(), v)

        # print owsrequest

        filenamenoextention = functions.set_path_filename(filedate,
                                               getparams['productcode'],
                                               getparams['subproductcode'],
                                               getparams['mapsetcode'],
                                               getparams['productversion'],
                                               '')
        owsrequest.setParameter("LAYERS", filenamenoextention)

        productmap = mapscript.mapObj(es_constants.template_mapfile)
        productmap.setConfigOption("PROJ_LIB", projlib)
        productmap.setConfigOption("MS_ERRORFILE", errorfile)
        productmap.maxsize = 4096

        outputformat_png = mapscript.outputFormatObj('GD/PNG', 'png')
        outputformat_png.setOption("INTERLACE", "OFF")
        productmap.appendOutputFormat(outputformat_png)
        #outputformat_gd = mapscript.outputFormatObj('GD/GIF', 'gif')
        #productmap.appendOutputFormat(outputformat_gd)
        productmap.selectOutputFormat('png')
        productmap.debug = mapscript.MS_TRUE
        productmap.status = mapscript.MS_ON
        productmap.units = mapscript.MS_DD

        coords = map(float, inputparams['BBOX'].split(","))
        print coords
        llx = coords[0]
        lly = coords[1]
        urx = coords[2]
        ury = coords[3]
        print llx, lly, urx, ury

        productmap.setExtent(llx, lly, urx, ury)   # -26, -35, 60, 38
        # productmap.setExtent(-26, -35, 60, 38)

        # epsg must be in lowercase because in unix/linux systems the proj filenames are lowercase!
        # epsg = "+init=epsg:3857"
        # epsg = "+init=" + inputparams.CRS.lower()   # CRS = "EPSG:4326"
        epsg = inputparams['CRS'].lower()   # CRS = "EPSG:4326"
        productmap.setProjection(epsg)

        w = int(inputparams['WIDTH'])
        h = int(inputparams['HEIGHT'])
        productmap.setSize(w, h)

        # General web service information
        productmap.setMetaData("WMS_TITLE", "Product description")
        productmap.setMetaData("WMS_SRS", inputparams['CRS'].lower())
        # productmap.setMetaData("WMS_SRS", "epsg:3857")
        productmap.setMetaData("WMS_ABSTRACT", "A Web Map Service returning eStation2 raster layers.")
        productmap.setMetaData("WMS_ENABLE_REQUEST", "*")   # necessary!!

        product_info = querydb.get_product_out_info(productcode=inputparams['productcode'],
                                                    subproductcode=inputparams['subproductcode'],
                                                    version=inputparams['productversion'])
        if hasattr(product_info, "__len__") and product_info.__len__() > 0:
            for row in product_info:
                scale_factor = row.scale_factor
                scale_offset = row.scale_offset
                nodata = row.nodata

        legend_info = querydb.get_legend_info(legendid=inputparams['legendid'])
        if hasattr(legend_info, "__len__") and legend_info.__len__() > 0:
            for row in legend_info:
                minstep = int((row.min_value - scale_offset)/scale_factor)    #int(row.min_value*scale_factor+scale_offset)
                maxstep = int((row.max_value - scale_offset)/scale_factor)    # int(row.max_value*scale_factor+scale_offset)
                realminstep = int((row.realminstep - scale_offset)/scale_factor)
                realmaxstep = int((row.realmaxstep - scale_offset)/scale_factor)
                minstepwidth = int((row.minstepwidth - scale_offset)/scale_factor)
                maxstepwidth = int((row.maxstepwidth - scale_offset)/scale_factor)
                totwidth = int((row.totwidth - scale_offset)/scale_factor)
                totsteps = row.totsteps

            # maxstep = 255
            processing_scale = 'SCALE='+str(minstep)+','+str(maxstep)  # min(legend_step.from_step) max(legend_step.to_step) example: 'SCALE=-7000,10000'

            minbuckets = 256
            maxbuckets = 10000
            num_buckets = maxbuckets
            if minstepwidth > 0:
                num_buckets = round(totwidth / minstepwidth, 0)

            if num_buckets < minbuckets:
                num_buckets = minbuckets
            elif num_buckets > maxbuckets:
                num_buckets = 0

            # num_buckets = 10000
            if num_buckets > 0:
                processing_buckets = 'SCALE_BUCKETS='+str(num_buckets)

            # nodata = -32768     # get this value from the table products.product
            processing_novalue = ''
            if nodata is not None and minstep <= nodata < maxstep:
                processing_novalue = 'NODATA='+str(nodata)

            layer = mapscript.layerObj(productmap)
            layer.name = filenamenoextention
            layer.type = mapscript.MS_LAYER_RASTER
            layer.status = mapscript.MS_ON     # MS_DEFAULT
            layer.data = productfile
            # layer.setProjection("+init=epsg:4326")
            layer.setProjection("epsg:4326")
            layer.dump = mapscript.MS_TRUE

            # scale & buckets
            if num_buckets > 0:
                layer.setProcessing(processing_scale)
                layer.setProcessing(processing_buckets)

            if processing_novalue != '':
                layer.setProcessing(processing_novalue)

            legend_steps = querydb.get_legend_steps(legendid=inputparams['legendid'])
            if hasattr(legend_steps, "__len__") and legend_steps.__len__() > 0:
                stepcount = 0
                for step in legend_steps:
                    stepcount += 1
                    min_step = int((step.from_step - scale_offset)/scale_factor)
                    max_step = int((step.to_step - scale_offset)/scale_factor)
                    colors = map(int, (color.strip() for color in step.color_rgb.split(" ") if color.strip()))

                    if stepcount == legend_steps.__len__():    # For the last step use <= max_step
                        expression_string = '([pixel] >= '+str(min_step)+' and [pixel] <= '+str(max_step)+')'
                    else:
                        expression_string = '([pixel] >= '+str(min_step)+' and [pixel] < '+str(max_step)+')'
                    # define class object and style
                    layerclass = mapscript.classObj(layer)
                    layerclass.name = layer.name+'_'+str(stepcount)
                    layerclass.setExpression(expression_string)
                    style = mapscript.styleObj(layerclass)
                    style.color.setRGB(colors[0], colors[1], colors[2])

        result_map_file = es_constants.apps_dir+'/analysis/MAP_result.map'
        # if os.path.isfile(result_map_file):
        #     os.remove(result_map_file)
        productmap.save(result_map_file)
        image = productmap.draw()
        image.save(es_constants.apps_dir+'/analysis/'+filenamenoextention+'.png')

        contents = productmap.OWSDispatch(owsrequest)
        content_type = mapscript.msIO_stripStdoutBufferContentType()
        content = mapscript.msIO_getStdoutBufferBytes()
        #web.header = "Content-Type","%s; charset=utf-8"%content_type
        # web.header('Content-type', 'image/png')
        #web.header('Content-transfer-encoding', 'binary')
        # return content

        self.assertEquals(True, True)
Example #24
0
    def wms(self):
        """This is a WMS endpoint.

        It uses mapserver mapscript to process a WMS request.

        This endpoint requires an additional WMS parameter
        DATA_URL. The DATA_URL, should point to a downloadable file
        which can be used as raster data input for mapserver.
        """
        LOG.debug('Processing ows request')

        data_url = None
        try:
            data_url = self.request.GET.getone('DATA_URL')
        except:
            LOG.warn('No data_url provided')
            data_url = None
            # FIXME: should return an error here)

        # get location of local data file
        loc = fetch_file(self.request, data_url)
        # get map
        map = self._get_map()
        # setup layer
        # TODO: improve selection of Layer generator
        # TODO: use python-magic for a more reliable mime type detection
        mimetype, encoding = mimetypes.guess_type(loc)
        if mimetype == 'image/tiff':
            layer = TiffLayer(self.request, loc)
        elif mimetype == 'text/csv':
            layer = CSVLayer(self.request, loc)
        elif mimetype == 'application/zip':
            datadir, filename = os.path.split(loc)
            # fname, fext = os.path.splitext(filename)

            # Check if shape/gdb file exists.
            # if os.path.isfile(os.path.join(datadir, fname + ".shp")):
            #    dbFilename = os.path.join(datadir, fname + ".shp")
            # elif os.path.isdir(os.path.join(datadir, fname)) and fname.endswith(".gdb"):
            #    dbFilename = os.path.join(datadir, fname)
            # else:
            #    msg = "Invalid zip file '{}' -- is not in shape/gdb format.".format(filename)
            #    raise HTTPNotImplemented(msg)

            # FIXME: filename shall be gdb/shape filename
            layer = ShapeLayer(self.request, filename)
        else:
            msg = "Unknown file type '{}'.".format(mimetype)
            # HTTPBadRequest(msg)
            raise HTTPNotImplemented(msg)

        # add layer into map
        idx = layer.add_layer_obj(map)
        # set map projection and extent from layer data
        lx = map.getLayer(idx).getExtent()
        map.extent = mapscript.rectObj(lx.minx, lx.miny, lx.maxx, lx.maxy)
        map.setProjection = "init={}".format(layer._data['crs'])

        # prepare an ows request object
        # do some map processing here
        ows_req = mapscript.OWSRequest()
        # our layer.add_layer_obj applies SLD and SLD_BODY
        # copy request params into ows request except not these two
        for k, v in ((k, v)for (k, v) in self.request.params.items() if k.lower() not in ('sld', 'sld_body', 'data_url')):
            ows_req.setParameter(k, v)
        # req.setParameter('SERVICE', 'WMS')
        # req.setParameter('VERSION', '1.3.0')
        # req.setParameter('REQUEST', 'GetCapablities')

        # here is probably some room for optimisation
        # e.g. let mapscript write directly to output?
        #      write tile to file system and serve tile via some other means?
        #      cache tile or at least mapobj?
        wms_req = self.request.params['REQUEST']
        wms_ver = self.request.params.get('VERSION', '1.3.0')
        # now do something based on REQUEST:
        if wms_req == u'GetMap':
            res = map.loadOWSParameters(ows_req, wms_ver)  # if != 0 then error
            img = map.draw()
            return Response(img.getBytes(), content_type=img.format.mimetype)
        elif wms_req == u'GetCapabilities':
            mapscript.msIO_installStdoutToBuffer()
            res = map.OWSDispatch(ows_req)  # if != 0 then error
            content_type = mapscript.msIO_stripStdoutBufferContentType()
            content = mapscript.msIO_getStdoutBufferBytes()
            return Response(content, content_type=content_type)
        elif wms_req == u'GetFeatureInfo':
            res = map.loadOWSParameters(ows_req, wms_ver)  # if != 0 then error
            mapscript.msIO_installStdoutToBuffer()
            res = map.OWSDispatch(ows_req)  # if != 0 then error
            content_type = mapscript.msIO_stripStdoutBufferContentType()
            content = mapscript.msIO_getStdoutBufferBytes()
            return Response(content, content_type=content_type)

        # We shouldn't end up here.....
        # let's raise an Error
        # FIXME: I am sure there are better pyramid ways to return errors
        raise Exception('request was not handled correctly')
Example #25
0
    def wfs(self):
        """This is a WFS endpoint.

        It uses mapserver mapscript to process a WFS request.

        This endpoint requires an additional WFS parameter
        DATA_URL. The DATA_URL, should point to a downloadable file
        which can be used as raster data input for mapserver.
        """
        LOG.debug('Processing ows request')

        data_url = None
        try:
            data_url = self.request.GET.getone('DATA_URL')
        except:
            LOG.warn('No data_url provided')
            data_url = None

        # get location of local data file
        # FIXME: May not be required if data is from DB
        if data_url:
            loc = fetch_file(self.request, data_url)

        # get map
        map = self._get_map()

        # Check that appropriate files are already exist.
        datadir, filename = os.path.split(loc)
        #fname, fext = os.path.splitext(filename)
        #if fext == '.zip':
        # Check if shape file exists.
        #if os.path.isfile(os.path.join(datadir, fname + ".shp")):
        #    dbFilename = os.path.join(datadir, fname + ".shp")
        #elif os.path.isdir(os.path.join(datadir, fname)) and fname.endswith(".gdb"):
        #    dbFilename = os.path.join(datadir, fname)
        #else:
        #    msg = "Invalid zip file '{}' -- is not in shape/gdb format.".format(filename)
        #    raise HTTPNotImplemented(msg)
        #else:
        #    raise HTTPNotImplemented("Invalid zip file '{}'".format(filename))

        # if DB server is configured, get layer data from DB server. Otherwise get data from db file.
        # FIXME: filename shall be gdb/shape filename
        layer = ShapeLayer(self.request, filename)

        # add the shape layer into map
        idx = layer.add_layer_obj(map)

        # set map projection and extent from layer data
        lx = map.getLayer(idx).getExtent()
        map.extent = mapscript.rectObj(lx.minx, lx.miny, lx.maxx, lx.maxy)
        map.setProjecntion = "init={}".format(layer._data['crs'])

        # prepare an ows request object by copying request params
        ows_req = mapscript.OWSRequest()
        ows_req.loadParamsFromURL(self.request.query_string)

        # here is probably some room for optimisation
        # e.g. let mapscript write directly to output?
        #      write tile to file system and serve tile via some other means?
        #      cache tile or at least mapobj?
        wfs_req = self.request.params['REQUEST']
        wfs_ver = self.request.params.get('VERSION', '1.1.0')

        # now do something based on REQUEST:
        mapscript.msIO_installStdoutToBuffer()
        res = map.OWSDispatch(ows_req)  # if != 0 then error
        content_type = mapscript.msIO_stripStdoutBufferContentType()
        content = mapscript.msIO_getStdoutBufferBytes()
        return Response(content, content_type=content_type)
Example #26
0
    def get(self, request, *args, **kwargs):
        """
        Html GET method of WmsView. This view renders WMS requests into
        corresponding responses using the attached WmsMap class.
        Responses are mainly images and xml files.
        """
        # Create response
        response = HttpResponse()

        # Setup wms request object
        ows_request = mapscript.OWSRequest()

        # If tile kwargs were provided, add tile parameters to request
        tileparams = self.tilemode()

        if tileparams:
            # Get image format from url
            format = {
                '.png': 'image/png',
                '.jpg': 'image/jpeg'
            }[self.kwargs.get('format')]

            # Return empty image if tile cant be found
            if not self.tile_exists(*tileparams):
                # Get image type and size
                imagetype = 'PNG' if format == 'image/png' else 'JPEG'
                imagesize = 256, 256
                response['Content-Type'] = format

                # Create image and save it to response
                im = Image.new("RGBA", imagesize, (0, 0, 0, 0))
                im.save(response, imagetype)

                return response
            else:
                tilebounds = self.get_tile_bounds(*tileparams)

                # Get layer name
                layers = self.kwargs.get('layers')

                # Setup wms parameter object
                request_data = {
                    'SERVICE': 'WMS',
                    'REQUEST': 'GetMap',
                    'VERSION': '1.1.1',
                    'TRANSPARENT': 'true',
                    'HEIGHT': '256',
                    'WIDTH': '256',
                    'SRS': 'EPSG:3857',
                    'FORMAT': format,
                    'LAYERS': layers,
                    'BBOX': tilebounds,
                }

                request.GET = dict(request.GET.items() + request_data.items())

        # Set ows parameters from request data
        for param, value in request.GET.items():
            ows_request.setParameter(param, value)

        # Instantiate WmsMap class
        self.wmsmap = self.map_class(request, **kwargs)

        # Dynamically use host for declaring service endpoint
        onlineresource = request.build_absolute_uri().split('?')[0] + '?'
        self.wmsmap.map_object.setMetaData('wms_onlineresource',
                                           onlineresource)

        # Dispatch map rendering
        self.wmsmap.map_object.OWSDispatch(ows_request)

        # Strip buffer from headers
        mapscript.msIO_stripStdoutBufferContentHeaders()

        # Store contenttype
        contenttype = mapscript.msIO_stripStdoutBufferContentType()

        # Write data to response
        response.write(mapscript.msIO_getStdoutBufferBytes())

        # Set contenttype
        response['Content-Type'] = contenttype

        return response
Example #27
0
map = mapscript.mapObj('../../tests/test.map')
map.setMetaData( "ows_onlineresource", "http://dummy.org/" )
ows_req = mapscript.OWSRequest()

ows_req.type = mapscript.MS_GET_REQUEST

ows_req.setParameter( "SERVICE", "WMS" );
ows_req.setParameter( "VERSION", "1.1.0" );
ows_req.setParameter( "REQUEST", "GetCapabilities" );

mapscript.msIO_installStdoutToBuffer()
dispatch_status = map.OWSDispatch(ows_req)
if dispatch_status:
    status = '200 OK'
else:
    status = '500 Internal Server Error'
content_type = mapscript.msIO_stripStdoutBufferContentType()
mapscript.msIO_stripStdoutBufferContentHeaders()
result = mapscript.msIO_getStdoutBufferBytes()

try:
    # MapServer 6.0:
    mapscript.msCleanup()
except:
    # MapServer 6.1:
    mapscript.msCleanup(1)

response_headers = [('Content-Type', content_type),
                    ('Content-Length', str(len(result)))]
Example #28
0
    def wfs(self):
        """This is a WFS endpoint.

        It uses mapserver mapscript to process a WFS request.

        This endpoint requires an additional WFS parameter
        DATA_URL. The DATA_URL, should point to a downloadable file
        which can be used as raster data input for mapserver.
        """
        LOG.debug("Processing ows request")

        data_url = None
        try:
            data_url = self.request.GET.getone("DATA_URL")
        except:
            LOG.warn("No data_url provided")
            data_url = None

        # get location of local data file
        # FIXME: May not be required if data is from DB
        if data_url:
            loc = fetch_file(self.request, data_url)

        # get map
        map = self._get_map()

        # Check that appropriate files are already exist.
        datadir, filename = os.path.split(loc)
        # fname, fext = os.path.splitext(filename)
        # if fext == '.zip':
        # Check if shape file exists.
        # if os.path.isfile(os.path.join(datadir, fname + ".shp")):
        #    dbFilename = os.path.join(datadir, fname + ".shp")
        # elif os.path.isdir(os.path.join(datadir, fname)) and fname.endswith(".gdb"):
        #    dbFilename = os.path.join(datadir, fname)
        # else:
        #    msg = "Invalid zip file '{}' -- is not in shape/gdb format.".format(filename)
        #    raise HTTPNotImplemented(msg)
        # else:
        #    raise HTTPNotImplemented("Invalid zip file '{}'".format(filename))

        # if DB server is configured, get layer data from DB server. Otherwise get data from db file.
        # FIXME: filename shall be gdb/shape filename
        layer = ShapeLayer(self.request, filename)

        # add the shape layer into map
        idx = layer.add_layer_obj(map)

        # set map projection and extent from layer data
        lx = map.getLayer(idx).getExtent()
        map.extent = mapscript.rectObj(lx.minx, lx.miny, lx.maxx, lx.maxy)
        map.setProjecntion = "init={}".format(layer._data["crs"])

        # prepare an ows request object by copying request params
        ows_req = mapscript.OWSRequest()
        ows_req.loadParamsFromURL(self.request.query_string)

        # here is probably some room for optimisation
        # e.g. let mapscript write directly to output?
        #      write tile to file system and serve tile via some other means?
        #      cache tile or at least mapobj?
        wfs_req = self.request.params["REQUEST"]
        wfs_ver = self.request.params.get("VERSION", "1.1.0")

        # now do something based on REQUEST:
        mapscript.msIO_installStdoutToBuffer()
        res = map.OWSDispatch(ows_req)  # if != 0 then error
        content_type = mapscript.msIO_stripStdoutBufferContentType()
        content = mapscript.msIO_getStdoutBufferBytes()
        return Response(content, content_type=content_type)
Example #29
0
    def get(self, request, *args, **kwargs):
        """
        Html GET method of WmsView. This view renders WMS requests into
        corresponding responses using the attached WmsMap class.
        Responses are mainly images and xml files.
        """
        # Create response
        response = HttpResponse()

        # Setup wms request object
        ows_request = mapscript.OWSRequest()

        # If tile kwargs were provided, add tile parameters to request
        tileparams = self.tilemode()

        if tileparams:
            # Get image format from url
            format = {'.png': 'image/png',
                      '.jpg': 'image/jpeg'}[self.kwargs.get('format')]

            # Return empty image if tile cant be found
            if not self.tile_exists(*tileparams):
                # Get image type and size
                imagetype = 'PNG' if format == 'image/png' else 'JPEG'
                imagesize = 256, 256
                response['Content-Type'] = format

                # Create image and save it to response
                im = Image.new("RGBA", imagesize, (0, 0, 0, 0))
                im.save(response, imagetype)

                return response
            else:
                tilebounds = self.get_tile_bounds(*tileparams)

                # Get layer name
                layers = self.kwargs.get('layers')

                # Setup wms parameter object
                request_data = {
                    'SERVICE': 'WMS',
                    'REQUEST': 'GetMap',
                    'VERSION': '1.1.1',
                    'TRANSPARENT': 'true',
                    'HEIGHT': '256',
                    'WIDTH': '256',
                    'SRS': 'EPSG:3857',
                    'FORMAT': format,
                    'LAYERS': layers,
                    'BBOX': tilebounds,
                }

                request.GET = dict(request.GET.items() + request_data.items())

        # Set ows parameters from request data
        for param, value in request.GET.items():
            ows_request.setParameter(param, value)

        # Instantiate WmsMap class
        self.wmsmap = self.map_class(request, **kwargs)

        # Dynamically use host for declaring service endpoint
        onlineresource = request.build_absolute_uri().split('?')[0] + '?'
        self.wmsmap.map_object.setMetaData('wms_onlineresource',
                                           onlineresource)

        # Dispatch map rendering
        self.wmsmap.map_object.OWSDispatch(ows_request)

        # Strip buffer from headers
        mapscript.msIO_stripStdoutBufferContentHeaders()

        # Store contenttype
        contenttype = mapscript.msIO_stripStdoutBufferContentType()

        # Write data to response
        response.write(mapscript.msIO_getStdoutBufferBytes())

        # Set contenttype
        response['Content-Type'] = contenttype

        return response
Example #30
0
    def wms(self):
        """This is a WMS endpoint.

        It uses mapserver mapscript to process a WMS request.

        This endpoint requires an additional WMS parameter
        DATA_URL. The DATA_URL, should point to a downloadable file
        which can be used as raster data input for mapserver.
        """
        LOG.debug('Processing ows request')

        data_url = None
        try:
            data_url = self.request.GET.getone('DATA_URL')
        except:
            LOG.warn('No data_url provided')
            data_url = None
            # FIXME: should return an error here)

        # get location of local data file
        loc = fetch_file(self.request, data_url)
        # get map
        map = self._get_map()
        # setup layer
        # TODO: improve selection of Layer generator
        # TODO: use python-magic for a more reliable mime type detection
        mimetype, encoding = mimetypes.guess_type(loc)
        if mimetype == 'image/tiff':
            layer = TiffLayer(self.request, loc)
        elif mimetype == 'text/csv':
            layer = CSVLayer(self.request, loc)
        elif mimetype == 'application/zip':
            datadir, filename = os.path.split(loc)
            # fname, fext = os.path.splitext(filename)

            # Check if shape/gdb file exists.
            # if os.path.isfile(os.path.join(datadir, fname + ".shp")):
            #    dbFilename = os.path.join(datadir, fname + ".shp")
            # elif os.path.isdir(os.path.join(datadir, fname)) and fname.endswith(".gdb"):
            #    dbFilename = os.path.join(datadir, fname)
            # else:
            #    msg = "Invalid zip file '{}' -- is not in shape/gdb format.".format(filename)
            #    raise HTTPNotImplemented(msg)

            # FIXME: filename shall be gdb/shape filename
            layer = ShapeLayer(self.request, filename)
        else:
            msg = "Unknown file type '{}'.".format(mimetype)
            # HTTPBadRequest(msg)
            raise HTTPNotImplemented(msg)

        # add layer into map
        idx = layer.add_layer_obj(map)
        # set map projection and extent from layer data
        lx = map.getLayer(idx).getExtent()
        map.extent = mapscript.rectObj(lx.minx, lx.miny, lx.maxx, lx.maxy)
        map.setProjection = "init={}".format(layer._data['crs'])

        # prepare an ows request object
        # do some map processing here
        ows_req = mapscript.OWSRequest()
        # our layer.add_layer_obj applies SLD and SLD_BODY
        # copy request params into ows request except not these two
        for k, v in ((k, v) for (k, v) in self.request.params.items()
                     if k.lower() not in ('sld', 'sld_body', 'data_url')):
            ows_req.setParameter(k, v)
        # req.setParameter('SERVICE', 'WMS')
        # req.setParameter('VERSION', '1.3.0')
        # req.setParameter('REQUEST', 'GetCapablities')

        # here is probably some room for optimisation
        # e.g. let mapscript write directly to output?
        #      write tile to file system and serve tile via some other means?
        #      cache tile or at least mapobj?
        wms_req = self.request.params['REQUEST']
        wms_ver = self.request.params.get('VERSION', '1.3.0')
        # now do something based on REQUEST:
        if wms_req == u'GetMap':
            res = map.loadOWSParameters(ows_req, wms_ver)  # if != 0 then error
            img = map.draw()
            return Response(img.getBytes(), content_type=img.format.mimetype)
        elif wms_req == u'GetCapabilities':
            mapscript.msIO_installStdoutToBuffer()
            res = map.OWSDispatch(ows_req)  # if != 0 then error
            content_type = mapscript.msIO_stripStdoutBufferContentType()
            content = mapscript.msIO_getStdoutBufferBytes()
            return Response(content, content_type=content_type)
        elif wms_req == u'GetFeatureInfo':
            res = map.loadOWSParameters(ows_req, wms_ver)  # if != 0 then error
            mapscript.msIO_installStdoutToBuffer()
            res = map.OWSDispatch(ows_req)  # if != 0 then error
            content_type = mapscript.msIO_stripStdoutBufferContentType()
            content = mapscript.msIO_getStdoutBufferBytes()
            return Response(content, content_type=content_type)

        # We shouldn't end up here.....
        # let's raise an Error
        # FIXME: I am sure there are better pyramid ways to return errors
        raise Exception('request was not handled correctly')
Example #31
0
    def render(self):
        """ Render this map object

            This will inspect the OWS request type, and render the correct image
            for the request.

            Known supported OWS REQUEST values:

            * GetLegendGraphic: Will render the legend for the OWS request
            * GetMap: Will render the map tile for the OWS request
        """

        log = logging.getLogger(__name__)

        content = None  # the bytes of the rendered image
        content_type = None  # the image mimetype
        retval = None  # the OWS return value, useful for debugging

        # TODO: do I need alock here?
        # with LockFile(self.data_file_path + '.lock'):
        if True:
            try:
                ows_request_type = self.ows_request.getValueByName('REQUEST')

                if (ows_request_type == 'GetLegendGraphic'):
                    # Draw the legend for the map
                    retval = self.loadOWSParameters(self.ows_request)
                    image = self.drawLegend()
                    content = image.getBytes()
                    content_type = image.format.mimetype
                elif (ows_request_type == 'GetMap'):
                    # Draw the map (tiles)
                    retval = self.loadOWSParameters(self.ows_request)
                    image = self.draw()
                    content = image.getBytes()
                    content_type = image.format.mimetype
                else:
                    # Unexpected OWS request. Do our best to support it by
                    # falling back to using the OWS Dispatch

                    # Tell mapscript to start capturing the stdout in a buffer
                    mapscript.msIO_installStdoutToBuffer()
                    # dispatch the OWS request
                    retval = self.OWSDispatch(self.ows_request)
                    # Get the content type of the return value
                    content_type = mapscript.msIO_stripStdoutBufferContentType(
                    )
                    # Get the content of the resulting image
                    content = mapscript.msIO_getStdoutBufferBytes()

                if retval != mapscript.MS_SUCCESS:
                    # Failed to render the desired image
                    raise RuntimeError("Failed to render map OWS request")

            except:
                log.error("Error while trying to render map: %s",
                          sys.exc_info()[0])
                raise
            finally:
                # Reset the mapscript I/O pointers back to where they should be
                mapscript.msIO_resetHandlers()

        return content, content_type, retval