Existe uma biblioteca Python para solicitar WMS / WFS e salvar como imagem / PDF?

18

Eu estou querendo saber se há lib GIS de código aberto Python que possui APIs para oferecer suporte a chamadas WMS / WFS de outro servidor GIS (por exemplo, GeoServer) e salvar os dados de resposta (mapa base do WMS e camada WFS) como imagens.

alguma recomendação?

obrigado por todas as entradas!

ATUALIZAÇÃO :

o que estou tentando fazer é um serviço de impressão de mapas, usando OpenLayers como front-end e Django como servidor; O usuário cliente define a extensão e as camadas e, em seguida, envia a solicitação de impressão (que se refere aos parâmetros, isto é, extensão do mapa, nomes das camadas) para o servidor. O servidor assume essa solicitação e chama WMS / WFS novamente usando parâmetros de solicitação, salve a resposta como PDF, exporte esse link PDF para o cliente.

A parte difícil é que, como o servidor chama o WMS / WFS e combina / sobrepõe essas respostas (ou seja, junta esses mapas / camadas, já que o WMS geralmente é o mapa base, o WFS aponta para as camadas de recursos), finalmente salva esse objeto combinado como imagem.

nas respostas atuais, o urllib parece ser bom, mas não sei como combinar essas respostas (WMS, WFSs); O OWSLib também parece outra boa opção, mas indica que é uma ferramenta de programação do cliente, estou um pouco confuso que seja apropriado para o meu uso ...

quaisquer outras entradas ??

apreciar!

Simon
fonte
Eu não acho que exista, mas é uma boa ideia!
OptimizePrime
Acabei de notar que a pergunta atualizada está relacionada à minha pergunta sobre a combinação de WMS em PDF.
MarkJ

Respostas:

18

Existe o OWSLib que deve fornecer exatamente o que você precisa.

OWSLib é um pacote Python para programação de clientes com padrões de interface de serviço da web Open Geospatial Consortium (OGC) (daí o OWS) e seus modelos de conteúdo relacionados.

O OWSLib fornece uma API comum para acessar metadados e wrappers de serviço para inúmeras interfaces de serviço da web do OGC.

Documentação e exemplos aqui . Cliente neste contexto significa que é um aplicativo cliente para um servidor WMS / WFS - ele pode ser executado em um servidor, se necessário.

Depois de adicionar mais detalhes à sua resposta, parece que o aplicativo de impressão MapFish atende exatamente às suas necessidades. É um aplicativo Java que pode ser integrado com OpenLayers e stitch tiles, WMS, WFS etc. juntos e produz um PDF.

Por ser um aplicativo de linha de comando, ele pode ser manipulado com um wrapper Python. Veja os links a seguir para mais detalhes:

http://geographika.co.uk/mapfish-print-module-for-iis

https://github.com/amercader/MapFish-Print-IIS

geographika
fonte
1
Obrigado pelo ponteiro para OWSLib, eu nunca tinha ouvido falar disso.
user2856
7

Você pode usar a biblioteca python urllib para chamar um WMS diretamente e gravar a resposta em um arquivo. Há um exemplo decente de uso do urllib nesta resposta . Basta substituir o URL por um para um WMS, por exemplo, http: //some.wms.service? Request = GetMap & VERSION = 1.1.1 & BBOX = 141.00, -29.00.141.80, -28.40 & SRS = EPSG: 4326 & LAYERS = LANDSAT_MOSAIC & WIDTH = 800 & HEIGHT = 600 & FORMAT = imagem / png .

Você também pode usar a biblioteca GDAL para acessar o WMS ( http://www.gdal.org/frmt_wms.html ) e a biblioteca OGR para acessar o WFS ( http://www.gdal.org/ogr/drv_wfs.html )

Se você quiser criar uma imagem do WFS, poderá usar a função gdal.RasterizeLayer para criar um jpg. Há um exemplo aqui .

user2856
fonte
2

Aqui está um exemplo simples. No lado do servidor:

def get_wfs():
    '''
    Get data from wfs server. Example url is:
    http://192.168.0.1:8080/geoserver/wfs?request=GetFeature&version=1.0.0&service=WFS&typeName=ChistaWS:Chista_new_POIs&maxfeatures=20&srsname=EPSG:4326&outputFormat=json
    We can add CQL filter like this:
    CQL_FILTER=name LIKE 'A%25'
    or
    CQL_FILTER=type=1913

    '''
    cql = ''
    if request.vars.cql:
        cql = urllib.quote_plus(request.vars.cql)
    req = 'GetFeature' # request
    version = '1.0.0'
    service = 'WFS'
    typeName = 'Test:Test_Places'
    maxfeatures = 200000
    if request.vars.mf:
        maxfeatures = request.vars.mf
    srsname = 'EPSG:4326'
    outputFormat = 'json'   
    # format_options = 'callback:getLayerFeatures_MY'
    wfs_url = '%s?request=%s&version=%s&service=%s&typeName=%s&maxfeatures=%s&srsname=%s&outputFormat=%s' % \
                (wfs_server, req, version, service, typeName,\
                 maxfeatures, srsname, outputFormat)
    if cql:
        # print cql
        wfs_url += '&CQL_FILTER=%s'%cql
    # print wfs_url
    try:
        jsonp = urllib2.urlopen(wfs_url).read()  # Get the raw server data
    except urllib2.HTTPError:
        return 'WFS Server <a target="_new" href="%s">%s</a> is down!' % (wfs_server, wfs_server)
    # return jsonp
    # try:
        # apijson = jsonp[ jsonp.index("(") + 1 : jsonp.rindex(")") ]
    # except ValueError:
    apijson = jsonp
    try:
        data = sj.loads(apijson)
    except sj.JSONDecodeError:
        return 'Can not parse data. No JSON! here is the data: <pre>%s</pre>' % apijson
    # return data
    features =[{
            'name':i['properties']['name'],
            'type':i['properties']['type'],
            'coordinates':i['geometry']['coordinates'],
            } for i in data['features']]
    # features =[i for i in data['features']]
    # return dict(features=features)
    return {'result':features, 'length':len(features)}

E no lado do cliente usando jquery:

$.ajax({
dataType : 'json',
url: wfsurl,
success  : function (response) {
if (response.length>0){
$('#'+subitem).empty();
for (var i = 0, len = response.length; i < len; i++) {
name = response.result[i].name;
lng = response.result[i].coordinates[0];
lat = response.result[i].coordinates[1];
// console.log(name, lng, lat)
html = '<li class="li-subitem"><a onclick="lazyview($(this));" lat="'+lat+'" lng="'+lng+'">'+name+'</a></li>';
$('#'+subitem).append(html);
}}
else{
$('#'+subitem).toggle(100);
}}});
Farsheed
fonte
0

Você pode usar o GeoTools para buscar os dados dos servidores WMS / WFS e renderizar em um objeto gráfico Java. Então, algo como o iText pode ser convertido para um pdf.

Se você realmente precisa usar o Python, espero que você possa usar um wrapper para gerenciar tudo.

Ian Turton
fonte
1
obrigado. mas eu só quero usar Python ... #
1116 Simon