GeonorgeAPI-et

GeonorgeAPIet er laget for å kommunisere med kartkatalogen.

Metadataene i Geonorge er lagret i formatet ISO19139. Dette er en stor og tung XML-standard som kan være krevende å jobbe med. I arbeidet med Geonorge oppstod det et behov for å manipulere metadataene programmatisk i jobben med å forbedre metadatakvaliteten. Det ble da utviklet et API for å kommunisere med kartkatalogen, samt en abstraksjonsklasse som gjør det lett å manipulere dataene.

Abstraksjonsklassen heter "SimpleMetadata" og tilbyr uthenting og oppdatering av felter i metadataene ved å bruke vanlige Property-felter.

Eksempel:

SimpleMetadata metadata = SimpleMetadata.CreateDataset(); metadata.Title = "This is my dataset!"; metadata.Abstract = "This is the abstract telling you everything you need to know about this dataset."; metadata.ContactPublisher = new SimpleContact {      Name = "John Smith",      Email = "nothing@example.com",      Organization = "My organization",      Role = "publisher" };

MD_Metadata_Type isoMetadata = metadata.GetMetadata();

Bruk og kildekode

SimpleMetadata gir deg mulighet til å hente ut et serialiserbart objekt av ISO19139-standarden som du nå enten kan skrive til fil eller sende avgårde ut på det store internettet. Om du er en av partene i Norge Digitalt og har fått tilgang til kartkatalogen så kan du selvsagt benytte deg av GeoNorgeAPIet for å gjøre denne oppdateringen.

GeoNorge api = new GeoNorge("myusername", "mypassword"); api.MetadataUpdate(isoMetadata);

Kildekoden til GeoNorgeAPI er gjort tilgjengelig på GitHub, men også som en NuGet-pakke som du kan installere slik:

PM> Install-Package GeoNorgeAPI

Hvordan søke etter tjenester i Geonorge?

For å finne frem til de geografiske tjenestene som er registrert i kartkatalogen til Geonorge så finnes det flere alternativer.

  1. Bruk kartkatalogens API for å få ut data i JSON-format.
  2. Bruk Geonorge APIet for å hente tjenester vha c# gjennom CSW-tjenesten til Geonorge.

Her forklares hvordan GeonorgeAPIet kan benyttes for å søke opp tjenester.

Det er forøvrig laget en demo som ligger ute på Geonorges GitHub område.

For å søke kun etter tjenester må du benytte søkefiltre. Bruk metoden SearchWithFilters i APIet.

Her er et eksempel på et søkefilter. Det består av selve filteret, pluss en array som inneholder navn på filteroperasjonen som skal benyttes som skal brukes. Dette er litt tungvindt, men dette er en konsekvens av den underliggende strukturen i CSW-standarden.

var searchFilter = new object[] { 
  new PropertyIsLikeType { 
    PropertyName = new PropertyNameType { Text = new[] { "Type" } }, 
    Literal = new LiteralType { Text = new[] { "service" } }  
  } 
}; 

var searchFilterNames = new[] { ItemsChoiceType23.PropertyIsLike };

Alle de ulike søkefiltrene er definert i en enum, www.opengis.net.ItemsChoiceType23:

namespace www.opengis.net
{
    [GeneratedCode("xsd", "4.0.30319.17929")]
    [XmlType(Namespace = "http://www.opengis.net/ogc", IncludeInSchema = false)]
    public enum ItemsChoiceType23
    {
        And,
        BBOX,
        Beyond,
        Contains,
        Crosses,
        DWithin,
        Disjoint,
        Equals,
        FeatureId,
        GmlObjectId,
        Intersects,
        Not,
        Or,
        Overlaps,
        PropertyIsBetween,
        PropertyIsEqualTo,
        PropertyIsGreaterThan,
        PropertyIsGreaterThanOrEqualTo,
        PropertyIsLessThan,
        PropertyIsLessThanOrEqualTo,
        PropertyIsLike,
        PropertyIsNotEqualTo,
        PropertyIsNull,
        Touches,
        Within,
        _Id,
        comparisonOps,
        logicOps,
        spatialOps
    }
}

Ønsker du å slå sammen flere filtre, kan du benytte de logiske operasjonene And, Not og Or.

Eksempel på filter for søk på tjenester fra Kartverket:

var searchFilter = new object[]
{
  new BinaryLogicOpType()
    {
      Items = new object[]
        {
          new PropertyIsLikeType
            {
              PropertyName = new PropertyNameType {Text = new[] {"OrganisationName"}},
              Literal = new LiteralType {Text = new[] { "Kartverket" }}
            },
          new PropertyIsLikeType
            {
              PropertyName = new PropertyNameType {Text = new[] {"Type"}},
              Literal = new LiteralType {Text = new[] { "service" }}
            }
        },
      ItemsElementName = new ItemsChoiceType22[]
        {
          ItemsChoiceType22.PropertyIsLike, ItemsChoiceType22.PropertyIsLike,
        }
    },
};

var searchFilterNames = new ItemsChoiceType23[]
{
  ItemsChoiceType23.And
};

Merk at vi bruker BineryLogicOpType på toppen og deretter bruker to stk. PropertIsLikeType. Disse slår vi så sammen med en And-operasjon. Se hvordan den underliggende CSW-requesten blir nedenfor. Mer informasjon om OGC Filter standarden finner du her.

Dette genererer en CSW-request som ser slik ut:

<?xml version="1.0" encoding="utf-8"?>
<csw:GetRecords xmlns:gmd="http://www.isotc211.org/2005/gmd"  
xmlns:gml="http://www.opengis.net/gml"
xmlns:gmx="http://www.isotc211.org/2005/gmx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:gco="http://www.isotc211.org/2005/gco"
xmlns:srv="http://www.isotc211.org/2005/srv"
xmlns:gts="http://www.isotc211.org/2005/gts"
service="CSW" version="2.0.2" resultType="results"
outputSchema="csw:Record" maxRecords="20"
xmlns:csw="http://www.opengis.net/cat/csw/2.0.2"> <csw:Query typeNames="csw:Record"> <csw:ElementSetName>full</csw:ElementSetName> <csw:Constraint version="1.1.0"> <Filter xmlns="http://www.opengis.net/ogc"> <And> <PropertyIsLike> <PropertyName>OrganisationName</PropertyName> <Literal>Kartverket</Literal> </PropertyIsLike> <PropertyIsLike> <PropertyName>Type</PropertyName> <Literal>service</Literal> </PropertyIsLike> </And> </Filter> </csw:Constraint> </csw:Query> </csw:GetRecords>

Dermed kan det brukes slik:

using System.Collections.Generic;
using GeoNorgeAPI;
using www.opengis.net;

namespace GeonorgeAPI.Demo.Console
{
    public class Program
    {
        private static GeoNorge _api = new GeoNorge();

        public static void Main(string[] args)
        {
            //SearchForServices();
            SearchForServicesFromKartverket();
        }

        private static void SearchForServices()
        {
            var searchFilter = new object[]
                {
                    new PropertyIsLikeType
                    {
                        PropertyName = new PropertyNameType {Text = new[] { "Type" }},
                        Literal = new LiteralType {Text = new[] { "service" }}
                    }
                };

            var searchFilterNames = new[]
                {
                    ItemsChoiceType23.PropertyIsLike,
                };

            SearchResultsType searchResults = _api.SearchWithFilters(searchFilter, 
searchFilterNames); List<CswMetadataEntry> metadataEntries = ParseSearchResults(searchResults); metadataEntries.ForEach(System.Console.WriteLine); } private static List<CswMetadataEntry> ParseSearchResults(SearchResultsType results) { List<CswMetadataEntry> metadatEntries = new List<CswMetadataEntry>(); if (results.Items != null) { foreach (var item in results.Items) { RecordType record = (RecordType)item; var metadataEntry = new CswMetadataEntry(); for (int i = 0; i < record.ItemsElementName.Length; i++) { var name = record.ItemsElementName[i]; var value = record.Items[i].Text != null ? record.Items[i].Text[0] :
null; if (name == ItemsChoiceType24.title) metadataEntry.Title = value; else if (name == ItemsChoiceType24.URI && value != null &&
value.StartsWith("http")) { metadataEntry.Uri = value; metadataEntry.Protocol =
((SimpleUriLiteral)record.Items[i]).protocol; } else if (name == ItemsChoiceType24.identifier) metadataEntry.Uuid = value; else if (name == ItemsChoiceType24.creator) metadataEntry.Creator = value; else if (name == ItemsChoiceType24.type) metadataEntry.Type = value; } metadatEntries.Add(metadataEntry); } } return metadatEntries; } private static void SearchForServicesFromKartverket() { var searchFilter = new object[] { new BinaryLogicOpType() { Items = new object[] { new PropertyIsLikeType { PropertyName = new PropertyNameType {Text = new[]
{"OrganisationName"}}, Literal = new LiteralType {Text = new[]
{ "Kartverket" }} }, new PropertyIsLikeType { PropertyName = new PropertyNameType
{Text = new[] {"Type"}}, Literal = new LiteralType {Text = new[]
{ "service" }} } }, ItemsElementName = new ItemsChoiceType22[] { ItemsChoiceType22.PropertyIsLike,
ItemsChoiceType22.PropertyIsLike, } }, }; var searchFilterNames = new ItemsChoiceType23[] { ItemsChoiceType23.And }; SearchResultsType searchResults = _api.SearchWithFilters(searchFilter,
searchFilterNames); List<CswMetadataEntry> metadataEntries = ParseSearchResults(searchResults); metadataEntries.ForEach(System.Console.WriteLine); } } }

Resultatet av kjøringen kan for eksempel se slik ut:

O-kartregisteret WFS [Kartverket]
         uuid=8d1550dd-34d8-4171-8a1e-544af46a8093
         uri=http://gis.umb.no/nof/o_kart_wfs?service=wfs&request=getcapabilities
         protocol=OGC:WFS
         type=service

O-kartregisteret WMS [Kartverket]
         uuid=b9c31c0a-b2b4-4c35-b94c-0db14bab5fec
         uri=http://gis.umb.no/nof/o_kart_wms
         protocol=OGC:WMS
         type=service

O-kartregisteret aktuelle kart WMS [Kartverket]
         uuid=5569f537-5f60-46a1-a501-ef2459269e4c
         uri=http://gis.umb.no/nof/o_kart_akt_wms
         protocol=OGC:WMS
         type=service

Kartverkets Elevation WPS [Kartverket]
         uuid=92299496-8836-4fc1-b685-6d14bd0eb749
         uri=http://wms.geonorge.no/skwms1/wps.elevation?
         protocol=WWW:LINK-1.0-http--link
         type=service

N5Raster2 WMS [Kartverket]
         uuid=79ea9761-1ac9-4780-a065-e4738835643e
         uri=http://wms.geonorge.no/skwms1/wms.n5raster2?
         protocol=OGC:WMS-1.3.0-http-get-map
         type=service

Tilgjengelighet2 WMS [Kartverket]
         uuid=b139a2c3-bdc3-4420-9def-4ce1080fcf0c
         uri=http://openwms.statkart.no/skwms1/wms.tilgjengelighet2?
         protocol=OGC:WMS
         type=service

Matrikkelen Web Services (SOAP) [Kartverket]
         uuid=56ec841f-fc71-4d0c-b4d4-5dec833dd01e
         uri=https://www.test.matrikkel.no/innsynapi_v3/docs/index.html
         protocol=W3C:WS
         type=service

Matrikkelens GeointegrasjonsAPI [Kartverket]
         uuid=fd905fcc-f5c3-450a-83d9-f35880aae1d7
         uri=https://www.test.matrikkel.no/geointegrasjonsapi_v1/docs/index.html
         protocol=W3C:WS
         type=service

Fjellskygge WMS [Kartverket]
         uuid=57bcf66a-1333-498f-a1f1-13f27a9cee1f
         uri=http://openwms.statkart.no/skwms1/wms.fjellskygge?
         protocol=OGC:WMS
         type=service

Toporaster 3 [Kartverket]
         uuid=13e15833-8d94-4b89-a53d-eb8da289677b
         uri=http://openwms.statkart.no/skwms1/wms.toporaster3?
         protocol=OGC:WMS
         type=service

Matrikkelens OppdateringsAPI [Kartverket]
         uuid=232eee00-951b-4ed8-8d0d-81fbb6f3a160
         uri=https://www.test.matrikkel.no/oppdateringapi_v3/docs/index.html
         protocol=WWW:LINK-1.0-http--link
         type=service

Adresse, Web Services (SOAP) [Kartverket]
         uuid=2fe0ca91-512b-4894-8afd-ebe8bfaf8cc9
         uri=
         protocol=
         type=service

Helse WMS [Kartverket]
         uuid=1a19e1e0-f97d-4ce8-84af-ec40f4809ad2
         uri=http://wms.geonorge.no/skwms1/wms.helse?
         protocol=OGC:WMS-1.1.1-http-get-map
         type=service

Transformasjon- Web Service [Kartverket]
         uuid=b0a3c1e7-36a8-4329-9c78-e8722145fb40
         uri=https://ws.geonorge.no/SKWS2/services/Tran?wsdl
         protocol=
         type=service