User:Esscue/OsmarenderOWL

From OpenStreetMap Wiki
Jump to: navigation, search

Devoloping my label placement optimizer I noticed that the SVG maps created with Osmarender lack some information that would be really useful. For example it is only possible to match labels by comparing coordinates to the features they describe or which area (or closed way) they belong to. Semantical information making the map accessible for a computer application would therefore be nice. Not only my application would profit from this information. These information could be used in a lot of contexts, here are some ideas:

So you see it sounds really nice, but how to do this?

A good friend of mine writing his diploma thesis about a topic in the area of semantic web gave me an initial hint with RDF (Resource Description Language). Doing some research on my own I came to OWL (Web Ontology Language) which seems to be the defacto standard for describing semantics. A concept called inference is also a plus for OWL. That means that a program is able to extract information from a OWL description that is not explicitly contained. There are a lot of tools for working with RDF/OWL:

As you can see it is possible with OWL to describe the map, but how to connect the features drawn on the map to their original OSM data?

Fortunately I found a young project, called linkedgeodata (http://linkedgeodata.org/About) publishing a RDF description of the whole OSM data. This RDF description of the OSM data will play a central role in my OWL description of the SVG maps.

Contents

OWL Ontology

Here is my first draft of an OWL ontology called svgmap for describing SVG maps created with Osmarender (Download):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
  <!ENTITY owl "http://www.w3.org/2002/07/owl#">
  <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
  <!ENTITY svgmap "http://www.openstreetmap.org/osmarender/ontology/svgmap/01/svgmap">
  <!ENTITY vocabulary "http://linkedgeodata.org/vocabulary">
  <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
]>
<rdf:RDF xml:base="&svgmap;"
         xmlns:owl="&owl;"
         xmlns:rdf="&rdf;"
         xmlns:rdfs="&rdfs;">
 
<!-- Ontology Information -->
  <owl:Ontology rdf:about="">
    <owl:imports>
      <owl:Ontology rdf:about="&vocabulary;"/>
    </owl:imports>
  </owl:Ontology>
 
<!-- Classes -->
  <owl:Class rdf:about="#AreaFeature">
    <rdfs:subClassOf rdf:resource="#Feature"/>
  </owl:Class>
 
  <owl:Class rdf:about="#AreaFeatureLabel">
    <rdfs:subClassOf rdf:resource="#Label"/>
  </owl:Class>
 
  <owl:Class rdf:about="#Feature"/>
  <owl:Class rdf:about="#Label"/>
  <owl:Class rdf:about="#LineFeature">
    <rdfs:subClassOf rdf:resource="#Feature"/>
  </owl:Class>
 
  <owl:Class rdf:about="#LineFeatureLabel">
    <rdfs:subClassOf rdf:resource="#Label"/>
  </owl:Class>
 
  <owl:Class rdf:about="#OSMArea">
    <rdfs:subClassOf rdf:resource="#OSMData"/>
    <owl:equivalentClass rdf:resource="http://linkedgeodata.org/triplify/way"/>
  </owl:Class>
 
  <owl:Class rdf:about="#OSMData"/>
  <owl:Class rdf:about="#OSMNode">
    <rdfs:subClassOf rdf:resource="#OSMData"/>
    <owl:equivalentClass rdf:resource="http://linkedgeodata.org/triplify/node"/>
  </owl:Class>
 
  <owl:Class rdf:about="#OSMWay">
    <rdfs:subClassOf rdf:resource="#OSMData"/>
    <owl:equivalentClass rdf:resource="http://linkedgeodata.org/triplify/way"/>
  </owl:Class>
 
  <owl:Class rdf:about="#PointFeature">
    <rdfs:subClassOf rdf:resource="#Feature"/>
  </owl:Class>
 
  <owl:Class rdf:about="#PointFeatureLabel">
    <rdfs:subClassOf rdf:resource="#Label"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGCircleElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGElement">
    <rdfs:subClassOf rdf:resource="#XMLElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGGElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGMap"/>
  <owl:Class rdf:about="#SVGPathElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGSVGElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGTextElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGTextPathElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#SVGUseElement">
    <rdfs:subClassOf rdf:resource="#SVGElement"/>
  </owl:Class>
 
  <owl:Class rdf:about="#XMLElement"/>
  <owl:Class rdf:about="http://linkedgeodata.org/triplify/node"/>
  <owl:Class rdf:about="http://linkedgeodata.org/triplify/way"/>
  <owl:Class rdf:nodeID="b19">
    <owl:unionOf rdf:parseType="Collection">
      <rdf:Description rdf:about="#SVGCircleElement"/>
      <rdf:Description rdf:about="#SVGGElement"/>
    </owl:unionOf>
  </owl:Class>
 
  <owl:Class rdf:nodeID="b18">
    <owl:unionOf rdf:parseType="Collection">
      <rdf:Description rdf:about="#SVGCircleElement"/>
      <rdf:Description rdf:about="#SVGPathElement"/>
    </owl:unionOf>
  </owl:Class>
 
<!-- Object Properties -->
  <owl:ObjectProperty rdf:about="#areaFeatureDrawnBy">
    <rdfs:domain rdf:resource="#AreaFeature"/>
    <rdfs:range rdf:nodeID="b18"/>
    <rdfs:subPropertyOf rdf:resource="#drawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#areaFeatureLabelDrawnBy">
    <rdfs:domain rdf:resource="#AreaFeatureLabel"/>
    <rdfs:range rdf:resource="#SVGTextElement"/>
    <rdfs:subPropertyOf rdf:resource="#labelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#areaFeatureShownBy">
    <rdfs:subPropertyOf rdf:resource="#shownBy"/>
    <owl:inverseOf rdf:resource="#showsAreaFeature"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#areaFeatureStandsFor">
    <rdfs:domain rdf:resource="#AreaFeature"/>
    <rdfs:range rdf:resource="#OSMArea"/>
    <rdfs:subPropertyOf rdf:resource="#standsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawnBy">
    <rdfs:domain rdf:resource="#Feature"/>
    <rdfs:range rdf:resource="#SVGElement"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#draws">
    <owl:inverseOf rdf:resource="#drawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsAreaFeature">
    <rdfs:subPropertyOf rdf:resource="#draws"/>
    <owl:inverseOf rdf:resource="#areaFeatureDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsAreaFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#drawsLabel"/>
    <owl:inverseOf rdf:resource="#areaFeatureLabelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsLabel">
    <owl:inverseOf rdf:resource="#labelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsLineFeature">
    <rdfs:subPropertyOf rdf:resource="#draws"/>
    <owl:inverseOf rdf:resource="#lineFeatureDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsLineFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#drawsLabel"/>
    <owl:inverseOf rdf:resource="#lineFeatureLabelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsPointFeature">
    <rdfs:subPropertyOf rdf:resource="#draws"/>
    <owl:inverseOf rdf:resource="#pointFeatureDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#drawsPointFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#drawsLabel"/>
    <owl:inverseOf rdf:resource="#pointFeatureLabelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#hasAreaFeatureLabel">
    <rdfs:domain rdf:resource="#AreaFeature"/>
    <rdfs:range rdf:resource="#AreaFeatureLabel"/>
    <rdfs:subPropertyOf rdf:resource="#hasLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#hasLabel">
    <rdfs:domain rdf:resource="#Feature"/>
    <rdfs:range rdf:resource="#Label"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#hasLineFeatureLabel">
    <rdfs:domain rdf:resource="#LineFeature"/>
    <rdfs:range rdf:resource="#LineFeatureLabel"/>
    <rdfs:subPropertyOf rdf:resource="#hasLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#hasNode">
    <rdfs:domain rdf:resource="#OSMWay"/>
    <rdfs:range rdf:resource="#OSMNode"/>
    <owl:equivalentProperty rdf:resource="http://linkedgeodata.org/triplify/hasNode"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#hasPointFeatureLabel">
    <rdfs:domain rdf:resource="#PointFeature"/>
    <rdfs:range rdf:resource="#PointFeatureLabel"/>
    <rdfs:subPropertyOf rdf:resource="#hasLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#isAreaFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#isLabel"/>
    <owl:inverseOf rdf:resource="#hasAreaFeatureLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#isLabel">
    <owl:inverseOf rdf:resource="#hasLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#isLineFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#isLabel"/>
    <owl:inverseOf rdf:resource="#hasLineFeatureLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#isNodeOf">
    <owl:inverseOf rdf:resource="#hasNode"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#isPointFeatureLabel">
    <rdfs:subPropertyOf rdf:resource="#isLabel"/>
    <owl:inverseOf rdf:resource="#hasPointFeatureLabel"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#labelDrawnBy">
    <rdfs:domain rdf:resource="#Label"/>
    <rdfs:range rdf:resource="#SVGElement"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#lineFeatureDrawnBy">
    <rdfs:domain rdf:resource="#LineFeature"/>
    <rdfs:range rdf:resource="#SVGUseElement"/>
    <rdfs:subPropertyOf rdf:resource="#drawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#lineFeatureLabelDrawnBy">
    <rdfs:domain rdf:resource="#LineFeatureLabel"/>
    <rdfs:range rdf:resource="#SVGTextElement"/>
    <rdfs:subPropertyOf rdf:resource="#labelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#lineFeatureShownBy">
    <rdfs:subPropertyOf rdf:resource="#shownBy"/>
    <owl:inverseOf rdf:resource="#showsLineFeature"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#lineFeatureStandsFor">
    <rdfs:domain rdf:resource="#LineFeature"/>
    <rdfs:range rdf:resource="#OSMWay"/>
    <rdfs:subPropertyOf rdf:resource="#standsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#pointFeatureDrawnBy">
    <rdfs:domain rdf:resource="#PointFeature"/>
    <rdfs:range rdf:nodeID="b19"/>
    <rdfs:subPropertyOf rdf:resource="#drawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#pointFeatureLabelDrawnBy">
    <rdfs:domain rdf:resource="#PointFeatureLabel"/>
    <rdfs:range rdf:resource="#SVGTextElement"/>
    <rdfs:subPropertyOf rdf:resource="#labelDrawnBy"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#pointFeatureShownBy">
    <rdfs:subPropertyOf rdf:resource="#shownBy"/>
    <owl:inverseOf rdf:resource="#showsPointFeature"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#pointFeatureStandsFor">
    <rdfs:domain rdf:resource="#PointFeature"/>
    <rdfs:range rdf:resource="#OSMNode"/>
    <rdfs:subPropertyOf rdf:resource="#standsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#shownBy">
    <owl:inverseOf rdf:resource="#shows"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#shows">
    <rdfs:domain rdf:resource="#SVGMap"/>
    <rdfs:range rdf:resource="#Feature"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#showsAreaFeature">
    <rdfs:range rdf:resource="#AreaFeature"/>
    <rdfs:subPropertyOf rdf:resource="#shows"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#showsLineFeature">
    <rdfs:range rdf:resource="#LineFeature"/>
    <rdfs:subPropertyOf rdf:resource="#shows"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#showsPointFeature">
    <rdfs:range rdf:resource="#PointFeature"/>
    <rdfs:subPropertyOf rdf:resource="#shows"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#standingFor">
    <owl:inverseOf rdf:resource="#standsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#standingForAreaFeature">
    <rdfs:subPropertyOf rdf:resource="#standingFor"/>
    <owl:inverseOf rdf:resource="#areaFeatureStandsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#standingForLineFeature">
    <rdfs:subPropertyOf rdf:resource="#standingFor"/>
    <owl:inverseOf rdf:resource="#lineFeatureStandsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#standingForPointFeature">
    <rdfs:subPropertyOf rdf:resource="#standingFor"/>
    <owl:inverseOf rdf:resource="#pointFeatureStandsFor"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="#standsFor">
    <rdfs:domain rdf:resource="#Feature"/>
    <rdfs:range rdf:resource="#OSMData"/>
  </owl:ObjectProperty>
 
  <owl:ObjectProperty rdf:about="http://linkedgeodata.org/triplify/hasNode">
    <owl:equivalentProperty rdf:resource="#hasNode"/>
  </owl:ObjectProperty>
</rdf:RDF>

Patch for Osmarender

Here you can download a patch for Osmarender that's will make the renderes add a OWL description of the map to the SVG metadata tag.

Features

Todos

Example

Here you find an example SVG file created with a patched version of Osmarender. For loading the OWL description in Swoop I created a xml file containing only the RDF part. To load the description, extract the xml file and load it into Swoop. After that load the ontology owl file from above and replace the defintions already loaded with the xml file. After that you can activate the Pellet reasoner and play around. Have fun:-)

Personal tools
Namespaces
Variants
Actions
site
Toolbox