JHS 193 Paikkatiedon yksilöivät tunnukset

Liite 2. Esimerkki tiedontuottajan URI-palvelun teknisestä toteutuksesta

  • Versio: 1.0
  • Julkaistu: 2.9.2015
  • Voimassaoloaika: toistaiseksi

1 Johdanto

Tässä liitteessä kuvataan esimerkki suosituksessa määriteltyjen vastauskäytänteiden mukaisen vastauksen antavan URI-palvelun teknisestä toteutuksesta. Toteutuksessa käytetyt tekniset ratkaisut ovat vain esimerkkejä. Vastauskäytänteiden mukaisen vastauksen tuottava palvelu on mahdollista toteuttaa monilla muillakin tavoilla. Tunnistettuja vaihtoehtoisia toteutustapoja on tuotu esille tekstissä.

Paikkatietokohteille, reaalimaailman kohteille ja käsitteille suosituksen mukaisesti annetut tunnukset sijaitsevat paikkatiedot.fi -verkkotunnuksen (domain) alla. Paikkatiedot.fi toimii kansallisena paikkatietojen URI-tunnusten uudelleenohjauspalveluna, joka ohjaa sille tulevat pyynnöt edelleen tiedon tuottajan tarjoamaan URI-palveluun.

URI-tunnuksiin kohdistuvat pyynnöt tulisi uudelleenohjata tiedon tuottajan tarjoamaan URI-palveluun, josta saatava vastaus on suosituksessa määritellyn vastauskäytänteen mukainen. Verkko-osoite (dokumentaation tunnus ”doc”, suosituksen kappale 9.1.4 ), johon paikkatietokohteen, reaalimaailman kohteen tai käsitteen tunnukseen tuleva kysely uudelleenohjataan, on yleisesti muotoa

http://{verkkotunnus}/doc/{aineistotunnus}/{paikallinen tunnus}[/{versiotunnus}]

2 URI-palvelun toimintaperiaate ja vastauskäytänteet

Object1

Paikkatiedot.fi -uudelleenohjauspalvelu ohjaa paikkatietokohteen, reaalimaailman kohteen tai käsitteen tunnukseen kohdistuvat pyynnöt tiedontuottajan URI-palveluun. URI-palvelu palauttaa paikkatietokohteeseen, reaalimaailman kohteeseen tai käsitteeseen liittyvän dokumentaation. Tässä esimerkkitoteutuksessa dokumentaatio on esitetty RDF/XML-muotoisena.

Dokumentaatio sisältää viittaukset:

  • dokumentoituun paikkatietokohteeseen, reaalimaailman kohteeseen tai käsitteeseen
  • jos dokumentaatio kohdistuu tietokohteeseen (paikkatietokohde tai käsite), kyseisen tietokohteen eri esitysmuotoihin (GML, JSON jne.), sekä
  • mahdollisuuksien mukaan
  • paikkatietokohdetta vastaavaan reaalimaailman kohteeseen
  • paikkatietokohdetta tai reaalimaailman kohdetta kuvaaviin käsitteisiin
  • muihin dokumentoituun paikkatietokohteeseen, reaalimaailman kohteeseen tai paikkatietokohteeseen liittyviin paikkatietokohteisiin, reaalimaailman kohteisiin, käsitteisiin tai muuhun dokumentaatioon (kuvat, tekstit jne.)

Tässä esimerkkitoteutuksessa URI-palvelu ohjaa paikkatietokohteiden esitysmuotojen kyselyt Web Feature Service -palvelulle, joka palauttaa kohteen tiedot halutussa koordinaatistossa ja formaatissa. Paikkatietokohteen eri esitysmuodot esitetään muodossa:

http://{verkkotunnus}/doc/{aineistotunnus}/{paikallinen tunnus}/{koordinaattijärjestelmä}.{formaatti}

esimerkiksi:

http://{verkkotunnus}/doc/{aineistotunnus}/{paikallinen tunnus}/EPSG:3087.gml2

URI-palvelun palauttaman RDF -tiedon tarkempi rakennekuvaus on esitelty luvussa 5. Luvussa 6.3 esitellään esimerkki tämän rakennekuvauksen mukaisesta RDF-tiedosta.

3 Tekniset vaatimukset

Tämän esimerkin URI-palvelun toteuttamiseen on käytetty seuraavia teknologioita:

  • Apache HTTP -palvelin
  • Apache Jena Fuseki RDF -palvelin

Apache HTTP- ja Apache Jena Fuseki -palvelimien käyttöönottoa ei tässä liitteessä ohjeisteta, vaan nämä on esitetty tuotteiden omilla verkkosivustoilla.

Apache Jena Fuseki -palvelinohjelmisto noudattaa SPARQL 1.1 -standardia, joten se on mahdollista korvata millä tahansa samaa standardia noudattavalla ohjelmistolla.

4 URI-palvelun toteutusvaiheet

Alla on esitetty esimerkki URI-palvelun toteutuksesta vaiheittain. Kaikki toteutuksessa käytetyt tiedostot on esitetty luvussa 6.

  1. Luodaan paikkatietokohteisiin liittyvän dokumentaation sisältävä, luvussa 5 esitetyn RDF-skeeman mukainen, SPARQL update -lause. Lause voidaan muodostaa WFS:n GetFeature kohdetietokyselyn palauttamasta GML-dokumentista XSLT-muunnoksella. Muunnoksen määrittelyyn ja suorittamiseen on olemassa hyviä valmiita sovelluksia verkossa. Esimerkkitoteutuksessa käytettävä XSLT-muunnostiedosto on esitetty luvussa 6.1. Jos paikkatietoaineisto on saatavana ajantasaisena tietokannassa ja halutaan välttää (mahdollisesti suurikokoisten) GML-dokumenttien käsittelyä, voidaan SPARQL update -lause vaihtoehtoisesti luoda sopivan skriptin avulla suoraan tietokannasta.
  2. Ladataan paikkatietokohteisiin liittyvä dokumentaatio kohdassa 1 muodostetulla SPARQL update -lauseella Apache Jena Fusekin RDF-tietokantaan. Vaihtoehtoisena toteutustapana kohdassa 1 GML-dokumentti (tai tietokannan sisältö) voidaan myös muuntaa (XSLT-muunnoksella tai muulla skriptillä) suoraan RDF/XML-muotoon ja ladata tämän jälkeen RDF-tietokantaan SPARQL LOAD -lauseella.
  3. Tehdään SPARQL-kysely Apache Jena Fuseki tietokantaan luvun 6.2 mukaisesti. Kysely palauttaa luvussa 5 määritellyn RDF -skeeman mukaiset tiedot, joista esimerkki luvussa 6.3. Vaihtoehtoisesti RDF-datan julkaisuun voidaan käyttää myös aputyökaluja kuten esim. Pubby (https://github.com/cygri/pubby) tai Elda (https://github.com/epimorphics/elda).
  4. Luodaan .htaccess -tiedosto Apache HTTP -palvelimelle, joka näkyy verkkoon. Luvussa 6.4 on esitetty esimerkki Apache .htaccess-uudelleenohjaustiedostosta selitettynä.

Huom! Tämä on tietyssä ympäristössä tehty esimerkkitoteutus. Näiden vaiheiden lisäksi voidaan joutua tekemään useita teknisiä konfigurointeja riippuen olemassa olevasta palvelinympäristöstä ja verkkoinfrastruktuurista.

5 URI-palvelun palauttaman RDF-tiedon rakennekuvaus

Alla olevassa taulukossa on esitetty URI-palvelun palauttaman RDF-muotoisen tiedon rakennekuvaus. Esimerkki kuvauksen mukaisesta RDF-vastauksesta on esitetty luvussa 6.3.

Luokka

Ominaisuus

Ominaisuuden arvoalue

Toistuvuus

Kuvaus

jhs:Doc

Resurssiin liittyvä dokumentaatio

jhs:so

Paikkatietokohteen tunnus

0..1

Jos dokumentoitu resurssi on paikkatietokohde, viittaus paikkatietokohteeseen, johon dokumentaatio kohdistuu

jhs:id

Reaalimaailman kohteen tunnus

0..1

Viittaus reaalimaailman kohteeseen, jota dokumentoitu paikkatietokohde mallintaa.

dct:hasFormat

jhs:Data

1..n

Resurssista saatavilla olevat esitysmuodot

dct:subject

Käsitteen tunnus

0..n

Viittaus resurssia kuvailevaan käsitteeseen

rdfs:seeAlso

Kohteeseen tai käsitteeseen liittyvää lisäinformaatiota

0..n

Viittaus esimerkiksi samaa reaalimaailman kohdetta mallintavaan paikkatietokohteeseen

jhs:Data

Resurssin esitysmuoto

jhs:CRS

Esitysmuodon koordinaattijärjestelmä

0..1

Esitysmuodon koordinaattijärjestelmän EPSG-koodi (vain paikkatietokohteille)

dc:format

Esitysmuodon formaatti

1

Esitysmuodon MIME-tyyppi

jhs:so

Paikkatietokohteen tunnus

0..1

Viittaus esitettävään paikkatietokohteeseen

jhs:def

Käsitteen tunnus

0..1

Viittaus esitettävään paikkatietokäsitteeseen

Taulukko 1. URI-palvelun palauttaman RDF-tiedon rakennekuvaus.

jhs: http://paikkatiedot.fi/jhs-skeema#

dc: http://purl.org/dc/elements/1.1/

dct: http://purl.org/dc/terms/

URI-palvelun tuottaja voi vapaasti soveltaa edellä määriteltyä RDF-rakennetta esim. laajentamalla sitä omilla elementeillään. Näitä voivat olla esimerkiksi erityyppiset linkitykset muihin tietokohteisiin. Myös paikkatietokohteen tai käsitteen tietosisältöä voidaan tuoda osaksi RDF-dokumentaatiota.

6 Esimerkkitiedostot

6.1 XSLT-muunnostiedosto

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:tampere_ora="http://www.navici.com/ns/tampere_ora" xmlns:gml="http://www.opengis.net/gml" >

<xsl:output method="text" indent="yes"/>

<xsl:template match="/">

PREFIX rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;
PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
PREFIX dc: &lt;http://purl.org/dc/elements/1.1/&gt;
PREFIX jhs: &lt;http://paikkatiedot.fi/jhs-skeema#&gt;

<!-- Muodostetaan SPARQL INSERT -lause. INSERT-lauseessa RDF-kolmikot esitetään Turtle-formaatissa. -->

INSERT DATA {

<xsl:for-each select="//tampere_ora:1000358_WB">

<!-- Paikkatietokohteeseen liittyvä dokumentaatio -->

&lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt; rdf:type jhs:Doc;
jhs:so &lt;http://paikkatiedot.fi/so/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt;;
jhs:id &lt;http://paikkatiedot.fi/id/1000040/<xsl:value-of select="tampere_ora:DIGIROAD_ID"/>&gt;;
rdfs:seeAlso &lt;http://paikkatiedot.fi/so/1000040/<xsl:value-of select="tampere_ora:DIGIROAD_ID"/>&gt;;
dct:hasFormat &lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3067.json&gt;;
dct:hasFormat &lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3067.gml2&gt;;
dct:hasFormat &lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3878.json&gt;;
dct:hasFormat &lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3878.gml2&gt;;
dct:subject &lt;http://www.yso.fi/onto/yso/p17892&gt;.

<!-- Paikkatietokohteen esitysmuodot -->

&lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3067.json&gt; rdf:type jhs:Data;
jhs:so &lt;http://paikkatiedot.fi/so/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt;;
jhs:CRS &lt;http://www.opengis.net/def/crs/EPSG/0/3067&gt;;
dc:format "application/json".

&lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3067.gml2&gt; rdf:type jhs:Data;
jhs:so &lt;http://paikkatiedot.fi/so/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt;;
jhs:CRS &lt;http://www.opengis.net/def/crs/EPSG/0/3067&gt;;
dc:format "application/gml".

&lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3878.json&gt; rdf:type jhs:Data;
jhs:so &lt;http://paikkatiedot.fi/so/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt;;
jhs:CRS &lt;http://www.opengis.net/def/crs/EPSG/0/3878&gt;;
dc:format "application/json".

&lt;http://kartat.tampere.fi/uri/doc/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>/EPSG:3878.gml2&gt; rdf:type jhs:Data;
jhs:so &lt;http://paikkatiedot.fi/so/1000358/<xsl:value-of select="tampere_ora:TUNNISTE"/>&gt;;
jhs:CRS &lt;http://www.opengis.net/def/crs/EPSG/0/3878&gt;;
dc:format "application/gml".

</xsl:for-each>

}

</xsl:template>

</xsl:stylesheet>

6.2 SPARQL-kysely

PREFIX rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
PREFIX rdfs: http://www.w3.org/2000/01/rdf-schema#
PREFIX dc: http://purl.org/dc/elements/1.1/
PREFIX jhs: <http://paikkatiedot.fi/jhs-skeema#>

CONSTRUCT {

<http://kartat.tampere.fi/uri/doc/1000358/0072> jhs:so ?so;
rdf:type ?a;
jhs:id ?h;
rdfs:seeAlso ?g;
dct:subject ?b;
dct:hasFormat ?c.
?c jhs:CRS ?d.
?c dc:format ?e.
?c rdf:type ?f
} WHERE
{
<http://kartat.tampere.fi/uri/doc/1000358/0072> jhs:so ?so;
rdf:type ?a;
jhs:id ?h;
rdfs:seeAlso ?g;
dct:subject ?b;
dct:hasFormat ?c.
?c jhs:CRS ?d.
?c dc:format ?e.
?c rdf:type ?f

}

6.3 RDF-esimerkki

<rdf:RDF

xmlns:jhs="http://paikkatiedot.fi/jhs-skeema#"

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:dc="http://purl.org/dc/elements/1.1/"

xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">

<jhs:Doc rdf:about="http://kartat.tampere.fi/uri/doc/1000358/6447">

<dct:hasFormat>

<jhs:Data rdf:about="http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.json">

<dc:format>application/json</dc:format>

<jhs:CRS rdf:resource="http://www.opengis.net/def/crs/EPSG/0/3067"/>

</jhs:Data>

</dct:hasFormat>

<dct:hasFormat>

<jhs:Data rdf:about="http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.gml2">

<dc:format>application/gml</dc:format>

<jhs:CRS rdf:resource="http://www.opengis.net/def/crs/EPSG/0/3067"/>

</jhs:Data>

</dct:hasFormat>

<dct:hasFormat>

<jhs:Data rdf:about="http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3878.json">

<dc:format>application/json</dc:format>

<jhs:CRS rdf:resource="http://www.opengis.net/def/crs/EPSG/0/3878"/>

</jhs:Data>

</dct:hasFormat>

<dct:hasFormat>

<jhs:Data rdf:about="http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3878.gml2">

<dc:format>application/gml</dc:format>

<jhs:CRS rdf:resource="http://www.opengis.net/def/crs/EPSG/0/3878"/>

</jhs:Data>

</dct:hasFormat>

<dct:subject rdf:resource="http://www.yso.fi/onto/yso/p17892"/>

<rdfs:seeAlso rdf:resource="http://paikkatiedot.fi/so/1000040/172353"/>

<jhs:id rdf:resource="http://paikkatiedot.fi/id/1000040/172353"/>

<jhs:so rdf:resource="http://paikkatiedot.fi/so/1000358/6447"/>

</jhs:Doc>

</rdf:RDF>

6.4 Turtle-esimerkki

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

@prefix jhs: <http://paikkatiedot.fi/jhs-skeema#> .

@prefix dc: <http://purl.org/dc/elements/1.1/> .

@prefix dct: <https://purl.org/dc/terms> .

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://kartat.tampere.fi/uri/doc/1000358/6447>

rdf:type jhs:doc ;

jhs:id <http://paikkatiedot.fi/id/1000040/172353> ;

jhs:so <http://paikkatiedot.fi/so/1000358/6447> ;

dc:subject <http://www.yso.fi/onto/yso/p17892> ;

rdfs:seeAlso <http://paikkatiedot.fi/so/1000040/172353> ;

dct:hasFormat <http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.gml2> ;

dct:hasFormat <http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.json> .

<http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.gml2>

rdf:type jhs:data ;

jhs:CRS <http://www.opengis.net/def/crs/EPSG/0/3067> ;

dc:format "application/gml" .

<http://kartat.tampere.fi/uri/doc/1000358/6447/EPSG:3067.json>

rdf:type jhs:data ;

jhs:CRS <http://www.opengis.net/def/crs/EPSG/0/3067> ;

dc:format "application/json" .

6.5 Apache .htaccess -tiedosto

<IfModule mod_rewrite.c>

RewriteEngine On

Rewritebase /uri/

# RewriteRule uudelleen ohjaa doc-polkukomponentin muuttujat ([a-zA-Z0-9]+)/([a-zA-Z0-9:]+).([a-zA-Z0-9]+) wfs-kohdekyselyyn $1,$2,$3. Huomaa, että RewriteRule tulee olla yhdellä rivillä, ei niin kuin alla esitetty.

RewriteRule ^doc/1000358/([a-zA-Z0-9_]+)/([a-zA-Z0-9:]+).([a-zA-Z0-9]+)$ http://tampere.navici.com/tampere_wfs_geoserver/tampere_ora/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=tampere_ora:BUSSIPYSAKIT_WB&outputformat=$3&srsName=$2&Filter=<Filter><PropertyIsEqualTo><PropertyName>TUNNISTE</PropertyName><Literal>$1</Literal></PropertyIsEqualTo></Filter>

RewriteRule ^doc/1000359/([a-zA-Z0-9_]+)/([a-zA-Z0-9:]+).([a-zA-Z0-9]+)$ http://tampere.navici.com/tampere_wfs_geoserver/tampere_ora/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=tampere_ora:BUSSILINJAT&outputformat=$3&srsName=$2&Filter=<Filter><PropertyIsEqualTo><PropertyName>REITTI</PropertyName><Literal>$1</Literal></PropertyIsEqualTo></Filter>

RewriteRule ^doc/1000378/([a-zA-Z0-9_-]+)/([a-zA-Z0-9:]+).([a-zA-Z0-9]+)$ http://tampere.navici.com/tampere_wfs_geoserver/rakennukset/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=rakennukset:RAKENN_ST_FA_MVIEW&outputformat=$3&srsName=$2&Filter=<Filter><PropertyIsEqualTo><PropertyName>RAK_TUNNUS_FACTA</PropertyName><Literal>$1</Literal></PropertyIsEqualTo></Filter>

RewriteRule ^doc/1000040/([a-zA-Z0-9_-]+)/([a-zA-Z0-9:]+).([a-zA-Z0-9]+)$ https://extranet.liikennevirasto.fi/inspirepalvelu/maaliikenne_avoin/wfs?request=GetFeature&typeName=maaliikenne_avoin:bussipysakit&srsName=$2&Filter=<Filter><PropertyIsLike+wildCard="*"+singleChar=","+escapeChar="."><PropertyName>STOP_ID</PropertyName><Literal>$1</Literal></PropertyIsLike></Filter>&outputformat=$3

#RewriteRule uudelleen ohjaa doc-polkukomponentin muuttujan ([a-zA-Z0-9]+) SPARQL-kyselyyn $1. Huomaa, että RewriteRule tulee olla yhdellä rivillä, ei niin kuin alla esitetty.

RewriteRule ^doc/1000358/([a-zA-Z0-9_-]+)$ http://kartat.tampere.fi/fuseki/ds2/query?query=PREFIX+rdf:+<http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX+rdfs:+<http://www.w3.org/2000/01/rdf-schema#>PREFIX+dc:+<http://purl.org/dc/elements/1.1/>PREFIX+jhs:+<http://paikkatiedot.fi/jhs-skeema#>CONSTRUCT+{<http://kartat.tampere.fi/uri/doc/1000358/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+WHERE{<http://kartat.tampere.fi/uri/doc/1000358/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+&output=xml

RewriteRule ^doc/1000358/([a-zA-Z0-9_-]+)/$ http://kartat.tampere.fi/fuseki/ds2/query?query=PREFIX+rdf:+<http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX+rdfs:+<http://www.w3.org/2000/01/rdf-schema#>PREFIX+dc:+<http://purl.org/dc/elements/1.1/>PREFIX+jhs:+<http://paikkatiedot.fi/jhs-skeema#>CONSTRUCT+{<http://kartat.tampere.fi/uri/doc/1000358/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+WHERE{<http://kartat.tampere.fi/uri/doc/1000358/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+&output=xml

RewriteRule ^doc/1000040/([a-zA-Z0-9_-]+)$ http://kartat.tampere.fi/fuseki/ds2/query?query=PREFIX+rdf:+<http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX+rdfs:+<http://www.w3.org/2000/01/rdf-schema#>PREFIX+dc:+<http://purl.org/dc/elements/1.1/>PREFIX+jhs:+<http://paikkatiedot.fi/jhs-skeema#>CONSTRUCT+{<http://kartat.tampere.fi/uri/doc/1000040/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+WHERE{<http://kartat.tampere.fi/uri/doc/1000040/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+&output=xml

RewriteRule ^doc/1000040/([a-zA-Z0-9_-]+)/$ http://kartat.tampere.fi/fuseki/ds2/query?query=PREFIX+rdf:+<http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX+rdfs:+<http://www.w3.org/2000/01/rdf-schema#>PREFIX+dc:+<http://purl.org/dc/elements/1.1/>PREFIX+jhs:+<http://paikkatiedot.fi/jhs-skeema#>CONSTRUCT+{<http://kartat.tampere.fi/uri/doc/1000040/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+WHERE{<http://kartat.tampere.fi/uri/doc/1000040/$1>+jhs:so+?jep;rdf:type+?f;jhs:id+?h;rdfs:seeAlso+?g;dct:subject+?a;dct:hasFormat+?b.?b+jhs:CRS+?c.?b+dc:format+?d.?b+rdf:type+?e}+&output=xml

</IfModule>