SlideShare une entreprise Scribd logo
1  sur  37
1




OGR2OSM
A powerful tool for converting geodata to .osm format
SOTM-US 2012
About
2




       What ogr2osm can do for you
       How ogr2osm works
       A case study of a data conversion
       Why care about converting?
Why care? To avoid this
3
History
4




       Written in 2009 by Iván Sánchez Ortega
       Rewritten 2012 by Andrew Guertin for UVM
        buildings
       I now maintain it
Features
5



       Can read any ogr supported data source
           .shp, .mdb, .gdb, sqlite, etc
       Reprojects if necessary – eliminates a step with many
        sources
       Works with multiple layer sources or shapefile
        directories
       Uses python translation functions that you write to
        convert source field values to OSM tags
           This allows you to use complicated logic to get the tagging right
       Documentation
Installing
6




       Requires gdal with python bindings
         Simply sudo apt-get install python-gdal git on
          Ubuntu
         May require compiling gdal from source and third-
          party SDKs for some formats (.mdb, .gdb)
       Run git   clone --recursive
        https://github.com/pnorman/ogr2osm   to install
       Full instructions at
        https://github.com/pnorman/ogr2osm
Code flow
7



    Read in data source          Process each layer            Merge nodes
    • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
      to read the files            tagging and objects         • Adjustable threshold for
                                                                 distance




    preOutputTransform()         Output XML
    • A user-defined filtering   • Write to a .osm file that
      step, not commonly used      can be opened in JOSM
Code flow
8



    Read in data source          Process each layer            Merge nodes
    • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
      to read the files            tagging and objects         • Adjustable threshold for
                                                                 distance




    preOutputTransform()         Output XML
    • A user-defined filtering   • Write to a .osm file that
      step, not commonly used      can be opened in JOSM
Code flow
9



    Read in data source          Process each layer            Merge nodes
    • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
      to read the files            tagging and objects         • Adjustable threshold for
                                                                 distance




    preOutputTransform()         Output XML
    • A user-defined filtering   • Write to a .osm file that
      step, not commonly used      can be opened in JOSM
Layer processing
10




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
11




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering
       EPSG:4326                           • Creates nodes and ways                                           step, not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
12




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
13




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
14




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
15




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering
       EPSG:4326                           • Creates nodes and ways                                           step, not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
16




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering
       EPSG:4326                           • Creates nodes and ways                                           step, not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
17




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Layer processing
18




     filterLayer()                         Reproject                         filterFeature()
     • Allows layers to be dropped         • Projects the layer into         • Allows features to be
     • Allows for the creation of new        EPSG:4326                         removed
       fields
       • e.g. a field that indicates the
         layer of a feature for later




     Reproject                             Convert to OSM                    filterTags()                   filterFeaturePost()
     • Projects the feature into           geometries                        • Where all the magic occurs   • A user-defined filtering step,
       EPSG:4326                           • Creates nodes and ways                                           not commonly used
                                           • Only creates multipolygons if
                                             necessary
Code flow
19



     Read in data source          Process each layer            Merge nodes
     • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
       to read the files            tagging and objects         • Adjustable threshold for
                                                                  distance




     preOutputTransform()         Output XML
     • A user-defined filtering   • Write to a .osm file that
       step, not commonly used      can be opened in JOSM
Code flow
20



     Read in data source          Process each layer            Merge nodes
     • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
       to read the files            tagging and objects         • Adjustable threshold for
                                                                  distance




     preOutputTransform()         Output XML
     • A user-defined filtering   • Write to a .osm file that
       step, not commonly used      can be opened in JOSM
Code flow
21



     Read in data source          Process each layer            Merge nodes
     • Uses python ogr bindings   • Converts from ogr to osm    • Merges duplicate nodes
       to read the files            tagging and objects         • Adjustable threshold for
                                                                  distance




     preOutputTransform()         Output XML
     • A user-defined filtering   • Write to a .osm file that
       step, not commonly used      can be opened in JOSM
Surrey case study
22



        Shapefile fields similar to other government GIS
         sources
        Fields or values periodically change with no notice
        58 layers in 7 zip files
            Not counting orthos and LIDAR-derived contours
        153 MB compressed, 1.7 GB uncompressed
        Covers 187 km2
        Too much data to write conversions for without a
         method
23
24
Reduce the amount of data
25



        ogr2osm will happily turn out a gigabyte .osm but
         good luck opening it
        Use ogr2ogr -spat to trim the input files down
            Converting from some formats to shapefiles will
             truncate field names
              Can use .gdb when coming from a format with long field
               names and layers
            -spat wants coordinates in layer coordinate system
              Use gdaltransform to turn latitude/longitude into desired
               coordinates
Drop layers
26


                                    def filterLayer(layer):
        Use the layer                layername = layer.GetName()
                                      if layername in ('WBD_HU2', 'WBD_HU4', 'WBD_HU6'):
         translation (-t layer)         return

         and see what layers         if layername not in ('NHDArea', 'NHDAreaEventFC'):
                                       print 'Unknown layer ' + layer.GetName()
         should be dropped           field = ogr.FieldDefn('__LAYER', ogr.OFTString)
                                     field.SetWidth(len(layername))
        Most multi-layer            layer.CreateField(field)


         sources have layers         for j in range(layer.GetFeatureCount()):
                                       ogrfeature = layer.GetNextFeature()

         that should not be            ogrfeature.SetField('__LAYER', layername)
                                       layer.SetFeature(ogrfeature)

         imported                    layer.ResetReading()
                                     return layer

        In the case of the
         Surrey data filtering is
         done in the script that
         downloads the data
Writing a good filterTags(attrs)
27



        When testing you       def filterTags(attrs):
                                  if not attrs: return
                                  tags = {}
         want unknown fields     if '__LAYER' in attrs and attrs['__LAYER'] ==

         to be kept                  'wtrHydrantsSHP':
                                   # Delete the warranty date
                                   if 'WARR_DATE' in attrs: del attrs['WARR_DATE']

        Delete items from         if 'HYDRANT_NO' in attrs:
                                     tags['ref'] = attrs['HYDRANT_NO'].strip()
         attrs as you convert        del attrs['HYDRANT_NO']
                                 elif '__LAYER' in attrs and attrs['__LAYER'] ==

         them to OSM tags            'trnRoadCentrelinesSHP':
                                   # ... More logic ...


        Delete fields which     for k,v in attrs.iteritems():
                                   if v.strip() != '' and not k in tags:

         shouldn’t be                tags[k]=v

                                 return tags
         converted to an OSM
         tag
What not to include
28




        Duplications of geodata
            SHAPE_AREA, SHAPE_LENGTH, latitude and
             longitude
        Unnecessary meta-data
          e.g. username of the last person in the GIS
           department to edit the object
          A single object ID can be useful but generally isn’t

        A good translation will often drop more than it
         includes
Identify the main field
29


                                       COMMENTS     LC_COST     RIGHTTO
        Convert to .osm with no       CONDDATE     LEFTFROM    ROADCODE
                                       CONDTN       LEFTTO      ROAD_NAME
         translation                   DATECLOSED   LEGACYID    ROW_WIDTH
                                       DATECONST    LOCATION    SNW_RTEZON
        View statistics about         DESIGNTN
                                       DISR_ROUTE
                                                    MATERIAL
                                                    MRN
                                                                SPEED
                                                                STATUS
         tags                          FAC_ID
                                       GCNAME
                                                    NO_LANE
                                                    OWNER
                                                                STR_ROUTE
                                                                TRK_ROUTE
            Easiest way is to open    GCPREDIR
                                       GCROADS
                                                    PAV_DATE
                                                    PROJ_NO
                                                                WAR_DATE
                                                                WTR_PRIOR
             in JOSM, select           GCSUFDIR     RC_TYPE     WTR_VEHCL
                                       GCTYPE       RC_TYPE2    YR
             ‐untagged, select the     GIS_ES       RD_CLASS    YTD_COST
                                       GREENWAY     RIGHTFROM
             tags, paste into a text
             editor                    NOT INCLUDED IN ROADS TRANSLATION
                                       NOT INCLUDED IN ANY TRANSLATION
                                       MAIN FIELD
        Need to look at a large
         area for this
The main field
30



        A numeric field and a text       RC_TYPE   RC_TYPE2      Count   Tagging

         field in this case               0         Road          11375   highway=?


        Don’t trust field                1         Frontage
                                                    Road
                                                                  38      highway=residential

         descriptions when writing        2         Highway               highway=motorway_link
                                                                  54
         OSM tagging                                Interchange

                                          3         Street Lane   20      highway=service
        Always verify!
                                          4         Access Lane           highway=?
            Access Lane would be                                 1442
             highway=service from the     5         Railway       28      railway=rail

             description but this would
             be wrong
            Use imagery, surveys or
             other sources
Looking at a value in more detail
31



        Should be carried out        RD_CLAS highway=            Coun
         for each value, even if      S                           t
         you think you’re sure        Local        residential    8284
         on the tagging               Major        tertiary       1350
                                      Collector
        Look at all tags for                      primary
         just those matching          Arterial                    1583
                                                   secondary
         the field value                           tertiary

                                      Provincial   motorway       156
            In this case search in                primary
             JOSM for                 Highway
             RC_TYPE2="Road"          Translink    unclassified   1
Even more detail
32



        Gets very close to            MRN   highway=    Count
         OSM tagging practice          Yes   secondary   504
         locally                       No    tertiary    1079
        Loss of information
         with Arterial MRN=No
         and Major Collector
         both mapping to
         tertiary
            Does this matter in
             this case? No, road
             classifications require
             some judgment
Dropping objects
33


                                  def filterFeature(ogrfeature, fieldNames, reproject):
        You may come across        if not ogrfeature: return


         objects that you          index = ogrfeature.GetFieldIndex('STATUS')
                                     if index >= 0 and ogrfeature.GetField(index) in
                                        ('History', 'For Construction', 'Proposed'):

         shouldn’t add to OSM            return None

                                   return ogrfeature

        In this case there are
         “paper roads” in the
         data
        Use filterFeature() to
         remove these
Putting it all together
34

     def filterLayer(layer):
       layername = layer.GetName()

      field = ogr.FieldDefn('__LAYER', ogr.OFTString)
                                                                Code presented is a
      field.SetWidth(len(layername))
      layer.CreateField(field)

      for j in range(layer.GetFeatureCount()):
                                                                 simplification and
        ogrfeature = layer.GetNextFeature()
        ogrfeature.SetField('__LAYER', layername)
        layer.SetFeature(ogrfeature)
                                                                 does not deal with
      layer.ResetReading()
      return layer                                               all fields
     def filterFeature(ogrfeature, fieldNames, reproject):
       if not ogrfeature: return
                                                                Filter features and
      index = ogrfeature.GetFieldIndex('STATUS')
        if index >= 0 and ogrfeature.GetField(index) in
           ('History', 'For Construction', 'Proposed'):
            return None
                                                                 layers
      return ogrfeature
Putting it all together
35

     def filterTags(attrs):
       if not attrs: return                                                            elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Provincial Highway':
       tags = {}                                                                         # Special-case motorways
                                                                                         if 'ROAD_NAME' in attrs and attrs['ROAD_NAME'] in
      if '__LAYER' in attrs and attrs['__LAYER'] ==                                          ('No 1 Hwy', 'No 99 Hwy'):
          'trnRoadCentrelinesSHP':                                                         tags['highway'] = 'motorway'
        if 'COMMENTS' in attrs: del attrs['COMMENTS']                                    else:
        if 'DATECLOSED' in attrs: del attrs['DATECLOSED']                                  tags['highway'] = 'primary'
        # Lots more to delete                                                              del attrs['RD_CLASS']
                                                                                         elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Translink':
        if 'NO_LANE' in attrs:                                                             tags['highway'] = 'unclassified'
          tags['lanes'] = attrs['NO_LANE'].strip()                                         del attrs['RD_CLASS']
          del attrs['NO_LANE']                                                           else:
                                                                                           l.error('trnRoadCentrelinesSHP RC_TYPE=0 logic fell through')
        if 'RC_TYPE' in attrs and attrs['RC_TYPE'].strip() == '0': # Normal roads          tags['fixme'] = 'yes'
          del attrs['RC_TYPE']                                                             tags['highway'] = 'road'
          if 'RC_TYPE2' in attrs: del attrs['RC_TYPE2']                              elif 'RC_TYPE' in attrs and attrs['RC_TYPE'].strip() == '1':
          if 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Local':                     # More logic
            tags['highway'] = 'residential'
            del attrs['RD_CLASS']                                                   elif '__LAYER' in attrs and attrs['__LAYER'] == 'trnTrafficSignalsSHP':
          elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Major Collector':        # More logic
            tags['highway'] = 'tertiary'
            del attrs['RD_CLASS']                                                   for k,v in attrs.iteritems():
          elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Arterial':               if v.strip() != '' and not k in tags:
            if 'ROAD_NAME' in attrs and attrs['ROAD_NAME'] in                           tags[k]=v
                ('King George Blvd', 'Fraser Hwy'):
              tags['highway'] = 'primary'                                           return tags
            else:
              if 'MRN' in attrs and attrs['MRN'] == 'Yes':
                tags['highway'] = 'secondary'
              else:
                tags['highway'] = 'tertiary'
            del attrs['RD_CLASS']
Any questions?
36
Credits
37




        Background by Stamen Design under CC BY
         3.0
        Surrey Data © 2012 City of Surrey under
         PDDL 1.0

Contenu connexe

Similaire à Ogr2osm presentation

Ospf and eigrp concepts and configuration
Ospf and eigrp concepts and configurationOspf and eigrp concepts and configuration
Ospf and eigrp concepts and configurationIT Tech
 
Apache Hadoop MapReduce Tutorial
Apache Hadoop MapReduce TutorialApache Hadoop MapReduce Tutorial
Apache Hadoop MapReduce TutorialFarzad Nozarian
 
Java10 and Java11 at JJUG CCC 2018 Spr
Java10 and Java11 at JJUG CCC 2018 SprJava10 and Java11 at JJUG CCC 2018 Spr
Java10 and Java11 at JJUG CCC 2018 Sprなおき きしだ
 
Yarn 3.1 and Beyond in ApacheCon North America 2018
Yarn 3.1 and Beyond in ApacheCon North America 2018Yarn 3.1 and Beyond in ApacheCon North America 2018
Yarn 3.1 and Beyond in ApacheCon North America 2018Naganarasimha Garla
 
Introduction to Docker (and a bit more) at LSPE meetup Sunnyvale
Introduction to Docker (and a bit more) at LSPE meetup SunnyvaleIntroduction to Docker (and a bit more) at LSPE meetup Sunnyvale
Introduction to Docker (and a bit more) at LSPE meetup SunnyvaleJérôme Petazzoni
 
Java user group 2015 02-09-java8
Java user group 2015 02-09-java8Java user group 2015 02-09-java8
Java user group 2015 02-09-java8marctritschler
 
Java user group 2015 02-09-java8
Java user group 2015 02-09-java8Java user group 2015 02-09-java8
Java user group 2015 02-09-java8Marc Tritschler
 
Apache spark - Spark's distributed programming model
Apache spark - Spark's distributed programming modelApache spark - Spark's distributed programming model
Apache spark - Spark's distributed programming modelMartin Zapletal
 
Pune-Cocoa: Blocks and GCD
Pune-Cocoa: Blocks and GCDPune-Cocoa: Blocks and GCD
Pune-Cocoa: Blocks and GCDPrashant Rane
 
Ippevent : openshift Introduction
Ippevent : openshift IntroductionIppevent : openshift Introduction
Ippevent : openshift Introductionkanedafromparis
 
Parallel computing with Gpu
Parallel computing with GpuParallel computing with Gpu
Parallel computing with GpuRohit Khatana
 
Bsdtw17: george neville neil: realities of dtrace on free-bsd
Bsdtw17: george neville neil: realities of dtrace on free-bsdBsdtw17: george neville neil: realities of dtrace on free-bsd
Bsdtw17: george neville neil: realities of dtrace on free-bsdScott Tsai
 
Finding Xori: Malware Analysis Triage with Automated Disassembly
Finding Xori: Malware Analysis Triage with Automated DisassemblyFinding Xori: Malware Analysis Triage with Automated Disassembly
Finding Xori: Malware Analysis Triage with Automated DisassemblyPriyanka Aash
 
DConf2015 - Using D for Development of Large Scale Primary Storage
DConf2015 - Using D for Development  of Large Scale Primary StorageDConf2015 - Using D for Development  of Large Scale Primary Storage
DConf2015 - Using D for Development of Large Scale Primary StorageLiran Zvibel
 
Lec 10-linux-review
Lec 10-linux-reviewLec 10-linux-review
Lec 10-linux-reviewabinaya m
 
High performance json- postgre sql vs. mongodb
High performance json- postgre sql vs. mongodbHigh performance json- postgre sql vs. mongodb
High performance json- postgre sql vs. mongodbWei Shan Ang
 

Similaire à Ogr2osm presentation (20)

Linux memory
Linux memoryLinux memory
Linux memory
 
Ospf and eigrp concepts and configuration
Ospf and eigrp concepts and configurationOspf and eigrp concepts and configuration
Ospf and eigrp concepts and configuration
 
Apache Hadoop MapReduce Tutorial
Apache Hadoop MapReduce TutorialApache Hadoop MapReduce Tutorial
Apache Hadoop MapReduce Tutorial
 
Java10 and Java11 at JJUG CCC 2018 Spr
Java10 and Java11 at JJUG CCC 2018 SprJava10 and Java11 at JJUG CCC 2018 Spr
Java10 and Java11 at JJUG CCC 2018 Spr
 
Yarn 3.1 and Beyond in ApacheCon North America 2018
Yarn 3.1 and Beyond in ApacheCon North America 2018Yarn 3.1 and Beyond in ApacheCon North America 2018
Yarn 3.1 and Beyond in ApacheCon North America 2018
 
Introduction to Docker (and a bit more) at LSPE meetup Sunnyvale
Introduction to Docker (and a bit more) at LSPE meetup SunnyvaleIntroduction to Docker (and a bit more) at LSPE meetup Sunnyvale
Introduction to Docker (and a bit more) at LSPE meetup Sunnyvale
 
Java user group 2015 02-09-java8
Java user group 2015 02-09-java8Java user group 2015 02-09-java8
Java user group 2015 02-09-java8
 
Java user group 2015 02-09-java8
Java user group 2015 02-09-java8Java user group 2015 02-09-java8
Java user group 2015 02-09-java8
 
Apache spark - Spark's distributed programming model
Apache spark - Spark's distributed programming modelApache spark - Spark's distributed programming model
Apache spark - Spark's distributed programming model
 
Pune-Cocoa: Blocks and GCD
Pune-Cocoa: Blocks and GCDPune-Cocoa: Blocks and GCD
Pune-Cocoa: Blocks and GCD
 
Pulsar
PulsarPulsar
Pulsar
 
Erlocator
ErlocatorErlocator
Erlocator
 
Ippevent : openshift Introduction
Ippevent : openshift IntroductionIppevent : openshift Introduction
Ippevent : openshift Introduction
 
Parallel computing with Gpu
Parallel computing with GpuParallel computing with Gpu
Parallel computing with Gpu
 
Driver_linux
Driver_linuxDriver_linux
Driver_linux
 
Bsdtw17: george neville neil: realities of dtrace on free-bsd
Bsdtw17: george neville neil: realities of dtrace on free-bsdBsdtw17: george neville neil: realities of dtrace on free-bsd
Bsdtw17: george neville neil: realities of dtrace on free-bsd
 
Finding Xori: Malware Analysis Triage with Automated Disassembly
Finding Xori: Malware Analysis Triage with Automated DisassemblyFinding Xori: Malware Analysis Triage with Automated Disassembly
Finding Xori: Malware Analysis Triage with Automated Disassembly
 
DConf2015 - Using D for Development of Large Scale Primary Storage
DConf2015 - Using D for Development  of Large Scale Primary StorageDConf2015 - Using D for Development  of Large Scale Primary Storage
DConf2015 - Using D for Development of Large Scale Primary Storage
 
Lec 10-linux-review
Lec 10-linux-reviewLec 10-linux-review
Lec 10-linux-review
 
High performance json- postgre sql vs. mongodb
High performance json- postgre sql vs. mongodbHigh performance json- postgre sql vs. mongodb
High performance json- postgre sql vs. mongodb
 

Dernier

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 

Dernier (20)

"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 

Ogr2osm presentation

  • 1. 1 OGR2OSM A powerful tool for converting geodata to .osm format SOTM-US 2012
  • 2. About 2  What ogr2osm can do for you  How ogr2osm works  A case study of a data conversion  Why care about converting?
  • 3. Why care? To avoid this 3
  • 4. History 4  Written in 2009 by Iván Sánchez Ortega  Rewritten 2012 by Andrew Guertin for UVM buildings  I now maintain it
  • 5. Features 5  Can read any ogr supported data source  .shp, .mdb, .gdb, sqlite, etc  Reprojects if necessary – eliminates a step with many sources  Works with multiple layer sources or shapefile directories  Uses python translation functions that you write to convert source field values to OSM tags  This allows you to use complicated logic to get the tagging right  Documentation
  • 6. Installing 6  Requires gdal with python bindings  Simply sudo apt-get install python-gdal git on Ubuntu  May require compiling gdal from source and third- party SDKs for some formats (.mdb, .gdb)  Run git clone --recursive https://github.com/pnorman/ogr2osm to install  Full instructions at https://github.com/pnorman/ogr2osm
  • 7. Code flow 7 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 8. Code flow 8 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 9. Code flow 9 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 10. Layer processing 10 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 11. Layer processing 11 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering EPSG:4326 • Creates nodes and ways step, not commonly used • Only creates multipolygons if necessary
  • 12. Layer processing 12 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 13. Layer processing 13 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 14. Layer processing 14 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 15. Layer processing 15 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering EPSG:4326 • Creates nodes and ways step, not commonly used • Only creates multipolygons if necessary
  • 16. Layer processing 16 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering EPSG:4326 • Creates nodes and ways step, not commonly used • Only creates multipolygons if necessary
  • 17. Layer processing 17 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 18. Layer processing 18 filterLayer() Reproject filterFeature() • Allows layers to be dropped • Projects the layer into • Allows features to be • Allows for the creation of new EPSG:4326 removed fields • e.g. a field that indicates the layer of a feature for later Reproject Convert to OSM filterTags() filterFeaturePost() • Projects the feature into geometries • Where all the magic occurs • A user-defined filtering step, EPSG:4326 • Creates nodes and ways not commonly used • Only creates multipolygons if necessary
  • 19. Code flow 19 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 20. Code flow 20 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 21. Code flow 21 Read in data source Process each layer Merge nodes • Uses python ogr bindings • Converts from ogr to osm • Merges duplicate nodes to read the files tagging and objects • Adjustable threshold for distance preOutputTransform() Output XML • A user-defined filtering • Write to a .osm file that step, not commonly used can be opened in JOSM
  • 22. Surrey case study 22  Shapefile fields similar to other government GIS sources  Fields or values periodically change with no notice  58 layers in 7 zip files  Not counting orthos and LIDAR-derived contours  153 MB compressed, 1.7 GB uncompressed  Covers 187 km2  Too much data to write conversions for without a method
  • 23. 23
  • 24. 24
  • 25. Reduce the amount of data 25  ogr2osm will happily turn out a gigabyte .osm but good luck opening it  Use ogr2ogr -spat to trim the input files down  Converting from some formats to shapefiles will truncate field names  Can use .gdb when coming from a format with long field names and layers  -spat wants coordinates in layer coordinate system  Use gdaltransform to turn latitude/longitude into desired coordinates
  • 26. Drop layers 26 def filterLayer(layer):  Use the layer layername = layer.GetName() if layername in ('WBD_HU2', 'WBD_HU4', 'WBD_HU6'): translation (-t layer) return and see what layers if layername not in ('NHDArea', 'NHDAreaEventFC'): print 'Unknown layer ' + layer.GetName() should be dropped field = ogr.FieldDefn('__LAYER', ogr.OFTString) field.SetWidth(len(layername))  Most multi-layer layer.CreateField(field) sources have layers for j in range(layer.GetFeatureCount()): ogrfeature = layer.GetNextFeature() that should not be ogrfeature.SetField('__LAYER', layername) layer.SetFeature(ogrfeature) imported layer.ResetReading() return layer  In the case of the Surrey data filtering is done in the script that downloads the data
  • 27. Writing a good filterTags(attrs) 27  When testing you def filterTags(attrs): if not attrs: return tags = {} want unknown fields if '__LAYER' in attrs and attrs['__LAYER'] == to be kept 'wtrHydrantsSHP': # Delete the warranty date if 'WARR_DATE' in attrs: del attrs['WARR_DATE']  Delete items from if 'HYDRANT_NO' in attrs: tags['ref'] = attrs['HYDRANT_NO'].strip() attrs as you convert del attrs['HYDRANT_NO'] elif '__LAYER' in attrs and attrs['__LAYER'] == them to OSM tags 'trnRoadCentrelinesSHP': # ... More logic ...  Delete fields which for k,v in attrs.iteritems(): if v.strip() != '' and not k in tags: shouldn’t be tags[k]=v return tags converted to an OSM tag
  • 28. What not to include 28  Duplications of geodata  SHAPE_AREA, SHAPE_LENGTH, latitude and longitude  Unnecessary meta-data  e.g. username of the last person in the GIS department to edit the object  A single object ID can be useful but generally isn’t  A good translation will often drop more than it includes
  • 29. Identify the main field 29 COMMENTS LC_COST RIGHTTO  Convert to .osm with no CONDDATE LEFTFROM ROADCODE CONDTN LEFTTO ROAD_NAME translation DATECLOSED LEGACYID ROW_WIDTH DATECONST LOCATION SNW_RTEZON  View statistics about DESIGNTN DISR_ROUTE MATERIAL MRN SPEED STATUS tags FAC_ID GCNAME NO_LANE OWNER STR_ROUTE TRK_ROUTE  Easiest way is to open GCPREDIR GCROADS PAV_DATE PROJ_NO WAR_DATE WTR_PRIOR in JOSM, select GCSUFDIR RC_TYPE WTR_VEHCL GCTYPE RC_TYPE2 YR ‐untagged, select the GIS_ES RD_CLASS YTD_COST GREENWAY RIGHTFROM tags, paste into a text editor NOT INCLUDED IN ROADS TRANSLATION NOT INCLUDED IN ANY TRANSLATION MAIN FIELD  Need to look at a large area for this
  • 30. The main field 30  A numeric field and a text RC_TYPE RC_TYPE2 Count Tagging field in this case 0 Road 11375 highway=?  Don’t trust field 1 Frontage Road 38 highway=residential descriptions when writing 2 Highway highway=motorway_link 54 OSM tagging Interchange 3 Street Lane 20 highway=service  Always verify! 4 Access Lane highway=?  Access Lane would be 1442 highway=service from the 5 Railway 28 railway=rail description but this would be wrong  Use imagery, surveys or other sources
  • 31. Looking at a value in more detail 31  Should be carried out RD_CLAS highway= Coun for each value, even if S t you think you’re sure Local residential 8284 on the tagging Major tertiary 1350 Collector  Look at all tags for primary just those matching Arterial 1583 secondary the field value tertiary Provincial motorway 156  In this case search in primary JOSM for Highway RC_TYPE2="Road" Translink unclassified 1
  • 32. Even more detail 32  Gets very close to MRN highway= Count OSM tagging practice Yes secondary 504 locally No tertiary 1079  Loss of information with Arterial MRN=No and Major Collector both mapping to tertiary  Does this matter in this case? No, road classifications require some judgment
  • 33. Dropping objects 33 def filterFeature(ogrfeature, fieldNames, reproject):  You may come across if not ogrfeature: return objects that you index = ogrfeature.GetFieldIndex('STATUS') if index >= 0 and ogrfeature.GetField(index) in ('History', 'For Construction', 'Proposed'): shouldn’t add to OSM return None return ogrfeature  In this case there are “paper roads” in the data  Use filterFeature() to remove these
  • 34. Putting it all together 34 def filterLayer(layer): layername = layer.GetName() field = ogr.FieldDefn('__LAYER', ogr.OFTString)  Code presented is a field.SetWidth(len(layername)) layer.CreateField(field) for j in range(layer.GetFeatureCount()): simplification and ogrfeature = layer.GetNextFeature() ogrfeature.SetField('__LAYER', layername) layer.SetFeature(ogrfeature) does not deal with layer.ResetReading() return layer all fields def filterFeature(ogrfeature, fieldNames, reproject): if not ogrfeature: return  Filter features and index = ogrfeature.GetFieldIndex('STATUS') if index >= 0 and ogrfeature.GetField(index) in ('History', 'For Construction', 'Proposed'): return None layers return ogrfeature
  • 35. Putting it all together 35 def filterTags(attrs): if not attrs: return elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Provincial Highway': tags = {} # Special-case motorways if 'ROAD_NAME' in attrs and attrs['ROAD_NAME'] in if '__LAYER' in attrs and attrs['__LAYER'] == ('No 1 Hwy', 'No 99 Hwy'): 'trnRoadCentrelinesSHP': tags['highway'] = 'motorway' if 'COMMENTS' in attrs: del attrs['COMMENTS'] else: if 'DATECLOSED' in attrs: del attrs['DATECLOSED'] tags['highway'] = 'primary' # Lots more to delete del attrs['RD_CLASS'] elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Translink': if 'NO_LANE' in attrs: tags['highway'] = 'unclassified' tags['lanes'] = attrs['NO_LANE'].strip() del attrs['RD_CLASS'] del attrs['NO_LANE'] else: l.error('trnRoadCentrelinesSHP RC_TYPE=0 logic fell through') if 'RC_TYPE' in attrs and attrs['RC_TYPE'].strip() == '0': # Normal roads tags['fixme'] = 'yes' del attrs['RC_TYPE'] tags['highway'] = 'road' if 'RC_TYPE2' in attrs: del attrs['RC_TYPE2'] elif 'RC_TYPE' in attrs and attrs['RC_TYPE'].strip() == '1': if 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Local': # More logic tags['highway'] = 'residential' del attrs['RD_CLASS'] elif '__LAYER' in attrs and attrs['__LAYER'] == 'trnTrafficSignalsSHP': elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Major Collector': # More logic tags['highway'] = 'tertiary' del attrs['RD_CLASS'] for k,v in attrs.iteritems(): elif 'RD_CLASS' in attrs and attrs['RD_CLASS'] == 'Arterial': if v.strip() != '' and not k in tags: if 'ROAD_NAME' in attrs and attrs['ROAD_NAME'] in tags[k]=v ('King George Blvd', 'Fraser Hwy'): tags['highway'] = 'primary' return tags else: if 'MRN' in attrs and attrs['MRN'] == 'Yes': tags['highway'] = 'secondary' else: tags['highway'] = 'tertiary' del attrs['RD_CLASS']
  • 37. Credits 37  Background by Stamen Design under CC BY 3.0  Surrey Data © 2012 City of Surrey under PDDL 1.0

Notes de l'éditeur

  1. HelloNameIntroduce selfHere to talk about ogr2osm
  2. I’ll talk aboutwhat ogr2osm can do for youHow it worksPresent a case studyBut first, why care?
  3. This is why you should careI wish I could say problems like this are uncommon but it didn’t take long for my database to find ways with over 300 tags from bad importsImports like this are useless with no osm tags and even if they include some osm tags the number of confusing tags puts new mappers off
  4. I did not start ogr2osm but I have taken over maintenance of it
  5. Ogr2osm has some features that make it superior to other general-purposeshapefile and geodata convertersBecause it uses ogr it can read virtually any file format. About the only format it doesn’t support is a postgisdb but that can be easily added if someone wants itIt reprojects to WGS84, saving a step with ogr2ogr with most sourcesIt will work with multi-layer sources, correctly combining shared nodes across layers with an error toleranceAnd most importantly, you can use python functions to convert datasource tags to OSM tagsLastly, it comes with some documentation
  6. Installing ogr2osm is fairly easy. The only dependencies are python and gdal with python bindings. Git is required to install it and the translationsShould mention Translations are their own git sub-module. This makes it possible to use your own repo for the translations without touching ogr2osm itself
  7. The easiest way for me to explain how ogr2osm works is to briefly run through the code execution
  8. First the file is read inBy default it reads with OGR it and it makes an in-memory copy of it
  9. Then it works on each layerOften there is just one layer but it will handle multiple ones
  10. A sequence of steps happens for each layer
  11. The first step for processing the layer is passing the layer through the filterLayer translation functionThis is a function that you can writeThere are two common usesThe first is to drop layers that you don’t want to convert to osm for importingThe second is to add new fields to the layer and to add fields to objects indicating what layer they’re from for later on
  12. The next step is to reproject the layer to EPSG:4326 that OSM usesOgr does all the work here so not much to say ---Next is filterFeature()Another user defined functionMost common use is to drop features that you aren’t interested---Each feature is turned from an ogr object into osm nodes ways and MPsThis is where the bulk of the code isOgr2osm will only create multipolygons if absolutely necessary. The old SVN version did so whenever there were overlapping ways but the new one does not do so.Intend to add this as an optionIt will handle stuff like multilinestrings without problemsIf you’re only using and not developing the details don’t matter too much---Next is the filterTags() functionThis is the most important user defined function. It turns source attributions into OSM tags and it’s up to you to write it. The use of a function allows complicated logic and stuff like name expansion---filterFeaturePost is another not commonly used function. UVM uses these for buildings in a fairly complicated way.--- You then repeat for each
  13. Next is filterFeature()Another user defined functionMost common use is to drop features that you aren’t interested
  14. In addition to each layer the features also need to be turned into EPSG:4326. not much to say here either
  15. Each feature is turned from an ogr object into osm nodes ways and MPsThis is where the bulk of the code isOgr2osm will only create multipolygons if absolutely necessary. The old SVN version did so whenever there were overlapping ways but the new one does not do so.Intend to add this as an optionIt will handle stuff like multilinestrings without problemsIf you’re only using and not developing the details don’t matter too much
  16. Next is the filterTags() functionThis is the most important user defined function. It turns source attributions into OSM tags and it’s up to you to write it. The use of a function allows complicated logic and stuff like name expansionAs it’s one argument it is passed a dictionary which is the fields on the feature and it returns another dictionary which is the OSM tags
  17. filterFeaturePost is another not commonly used function. UVM uses these for buildings in a fairly complicated way.--- You then repeat for each
  18. You then repeat for each
  19. As an example of writing translations, I have a case study of data from the City of Surrey that I’ve been working onThis is a large and extremely detailed data setI should mention that converting the data is only half the problem. Once it’s converted you have to figure out how to best use the data, but that’s another talk in itselfAlthough I am looking at one specific dataset most government datasets are fairly similar in what they tag and how their taggings don’t exactly correspond to OSM taggingsWhat do I mean by a lot of data?
  20. This is about 10x5 city blocks, about 40 hectares. As you can see, there’s a lot of data
  21. This is one corner showing how much data there is to sort through, but I won’t go over all of it here
  22. The first step is generally to clip the data to a smaller areaogr2osm will deal with gigabyte .osm files but normally you want to load these up into JOSM which doesn’t work so wellOgr2ogr can trim the files down to an area, but you need to be aware of a couple gotchasIf your source is .mdb or something that supports long field names converting to a shapefile will truncate themYou also have to deal with coordinate systems. I have a one line command in my speaker’s notes that will be up later that does thisI have a one-line ogr2ogr command in my notes that handlesogr2ogr -progress -spat `echo "-122.89 49.18" | gdaltransform -s_srs EPSG:4326 -t_srs EPSG:26910 | cut -d \\ -f 1,2` `echo "-122.85 49.22" | gdaltransform -s_srs EPSG:4326 -t_srs EPSG:26910 | cut -d \\ -f 1,2` SurreyData_clipSurreyData
  23. The first step is to see what layers you can dropThe easiest way to do this is use the layer translation and open the resulting .osm fileI’m have scripting for the surrey example before it makes it to ogr2osm that removes the undesired layers so this example is actually from a NHD translationIt removes some layers which indicate NHD subbasin divisions which don’t correspond to anything physicalIt also adds a __LAYER field which is needed to identify which layer a feature comes from
  24. With a complex shapefile there might be 50 fields to use when converting to OSM tags, so it really helps to have a system for writing your filterTags functionThis is the system I use, with an exampleThis function first exits if it’s an untagged object like a nodeIt then deletes some items from attrs and converts one to a ref tagIt then adds any unknown fields as tagsFor an automatically run script you’d want to make it error if it came across unknown fields since this would indicate the fields had changed
  25. The first stop to writing a good filtertags is to get rid of most of the fieldsDepending on how the data was generated you’ll have a lot of useless fields. The surrey data is basically a dump out of their database so it includes every possible field
  26. The first step is to identify the main field for the layer. Most layers will have some kind of main field.In this case there are a total of 44 fields. 17 can be dropped right away and it’s helpful to do this just to clear up what you’re looking at
  27. In this case the main field is RC_TYPE and RC_TYPE2Generally the main field will give you the main tagIn this case it tells you that some are highways and others are railways but doesn’t always tell you what type of highwayThe important point is, and I cannot emph. this enough, is to always verify the fields. You cannot assume that the descriptions mean what you think they doFor a big dataset like NHD you can’t even assume that it’s consistent across the countryBecause road is ambiguous we need to look at it in more detail
  28. Once you’ve identified a value, in this case RC_TYPE2=Road you want to then look at that in detail.As you can see, we still don’t have enough detail to reliably tag the class of road for RD_CLASS arterial, so we need to look for more detail