Skip to content

Commit

Permalink
#15 Use ogr2osm in stead of root logger
Browse files Browse the repository at this point in the history
  • Loading branch information
roelderickx committed Nov 7, 2021
1 parent 4a92576 commit a9965a7
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 59 deletions.
60 changes: 31 additions & 29 deletions ogr2osm/ogr2osm.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@
from .osm_datawriter import OsmDataWriter
from .pbf_datawriter import is_protobuf_installed, PbfDataWriter

logging.basicConfig(format="%(message)s", level = logging.DEBUG)

def parse_commandline():
def parse_commandline(logger):
parser = argparse.ArgumentParser(prog=__program__)

#parser.add_argument("-v", "--verbose", dest="verbose", action="store_true")
Expand Down Expand Up @@ -166,35 +164,35 @@ def parse_commandline():
else:
(base, ext) = os.path.splitext(params.outputFile)
if params.pbf and ext.lower() == '.osm':
logging.warning("WARNING: You specified PBF output with --pbf "
"but the outputfile has extension .osm, "
"ignoring --pbf parameter")
logger.warning("WARNING: You specified PBF output with --pbf "
"but the outputfile has extension .osm, "
"ignoring --pbf parameter")
params.pbf = False
elif is_protobuf_installed and not params.pbf and ext.lower() == '.pbf':
logging.warning("WARNING: You didn't specify PBF output with --pbf "
"but the outputfile has extension .pbf, "
"automatically setting --pbf parameter")
logger.warning("WARNING: You didn't specify PBF output with --pbf "
"but the outputfile has extension .pbf, "
"automatically setting --pbf parameter")
params.pbf = True
elif not is_protobuf_installed and not params.pbf and ext.lower() == '.pbf':
logging.warning("WARNING: PBF output is not supported on this "
"system but the outputfile has extension .pbf, "
"automatically removing .pbf extension")
logger.warning("WARNING: PBF output is not supported on this "
"system but the outputfile has extension .pbf, "
"automatically removing .pbf extension")
(base_osm, ext_osm) = os.path.splitext(base)
if ext_osm == '.osm':
params.outputFile = base
else:
params.outputFile = base + '.osm'
if params.sqlQuery:
logging.warning("WARNING: You specified a query with --sql "
"but you are not using a database source")
logger.warning("WARNING: You specified a query with --sql "
"but you are not using a database source")

if not params.forceOverwrite and os.path.exists(params.outputFile):
parser.error("ERROR: output file '%s' exists" % params.outputFile)

return params


def load_translation_object(translation_module):
def load_translation_object(logger, translation_module):
translation_object = None

if translation_module:
Expand All @@ -216,47 +214,51 @@ def load_translation_object(translation_module):
try:
imported_module = __import__(translation_module)
except ImportError as e:
logging.error("Could not load translation method '%s'. Translation "
"script must be in your current directory, or in the "
"translations/ subdirectory of your current directory. "
"The following directories have been considered: %s",
translation_module, str(sys.path))
logger.error("Could not load translation method '%s'. Translation "
"script must be in your current directory, or in the "
"translations/ subdirectory of your current directory. "
"The following directories have been considered: %s",
translation_module, str(sys.path))
except SyntaxError as e:
logging.error("Syntax error in '%s'. Translation script is malformed:\n%s",
translation_module, e)
logger.error("Syntax error in '%s'. Translation script is malformed:\n%s",
translation_module, e)

for class_name in [ d for d in dir(imported_module) \
if d != 'TranslationBase' and not d.startswith('__') ]:
translation_class = getattr(imported_module, class_name)

if inspect.isclass(translation_class) and \
issubclass(translation_class, TranslationBase):
logging.info('Found valid translation class %s', class_name)
logger.info('Found valid translation class %s', class_name)
setattr(sys.modules[__name__], class_name, translation_class)
translation_object = translation_class()
break

if not translation_object:
if translation_module:
logging.warning('WARNING: translation file does not contain a valid translation class')
logging.warning('Falling back to DEFAULT translations')
logger.warning('WARNING: translation file does not contain a valid translation class')
logger.warning('Falling back to DEFAULT translations')
else:
logging.info('Using default translations')
logger.info('Using default translations')
translation_object = TranslationBase()

return translation_object


def main():
params = parse_commandline()
logger = logging.getLogger(__program__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())

params = parse_commandline(logger)

translation_object = load_translation_object(params.translationmodule)
translation_object = load_translation_object(logger, params.translationmodule)

OsmId.set_id(params.id, params.positiveId)
if params.idfile:
OsmId.load_id(params.idfile)

logging.info("Preparing to convert '%s' to '%s'.", params.source, params.outputFile)
logger.info("Preparing to convert '%s' to '%s'.", params.source, params.outputFile)

osmdata = OsmData(translation_object, \
params.roundingDigits, params.maxNodesPerWay, params.addBounds)
Expand Down
22 changes: 14 additions & 8 deletions ogr2osm/ogr_datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
accompany any distribution of this code.
'''

import os, logging
import os
import logging
from osgeo import gdalconst
from osgeo import ogr
from osgeo import osr

from .version import __program__

class OgrDatasource:
def __init__(self, translation, source_proj4=None, source_epsg=None, gisorder=False, \
source_encoding='utf-8'):
self.logger = logging.getLogger(__program__)
self.datasource = None
self.is_database_source = False
self.query = None
Expand All @@ -39,7 +43,8 @@ def open_datasource(self, ogrpath, prefer_mem_copy=True):
ogr_unsupported = [ "vsimem", "vsistdout" ]
has_unsup = [ m for m in ogr_unsupported if m in ogrpath.split('/') ]
if has_unsup:
logging.error("Unsupported OGR access method(s) found: %s.", ', '.join(has_unsup))
self.logger.error("Unsupported OGR access method(s) found: %s.", \
', '.join(has_unsup))

# using ogr access methods ?
ogr_accessmethods = [ "vsicurl", "vsicurl_streaming", "vsisubfile", "vsistdin" ]
Expand All @@ -56,7 +61,7 @@ def open_datasource(self, ogrpath, prefer_mem_copy=True):
break

if not os.path.exists(filename):
logging.error("The file '%s' does not exist.", filename)
self.logger.error("The file '%s' does not exist.", filename)
elif ogrpath == filename:
if filename.endswith('.tar') or \
filename.endswith('.tgz') or \
Expand All @@ -79,9 +84,10 @@ def open_datasource(self, ogrpath, prefer_mem_copy=True):
self.datasource = ogr.Open(full_ogrpath, gdalconst.GA_ReadOnly)

if self.is_database_source and not self.datasource:
logging.error("OGR failed to open connection to %s.", full_ogrpath)
self.logger.error("OGR failed to open connection to %s.", full_ogrpath)
elif not self.is_database_source and not self.datasource and not file_datasource:
logging.error("OGR failed to open '%s', format may be unsupported.", full_ogrpath)
self.logger.error("OGR failed to open '%s', format may be unsupported.", \
full_ogrpath)
elif not self.is_database_source and file_datasource and prefer_mem_copy:
mem_driver = ogr.GetDriverByName('Memory')
self.datasource = mem_driver.CopyDataSource(file_datasource, 'memoryCopy')
Expand All @@ -107,9 +113,9 @@ def __get_source_reprojection_func(self, layer):
spatial_ref.ImportFromEPSG(self.source_epsg)
elif layer_spatial_ref:
spatial_ref = layer_spatial_ref
logging.info("Detected projection metadata:\n%s", str(layer_spatial_ref))
self.logger.info("Detected projection metadata:\n%s", str(layer_spatial_ref))
else:
logging.info("Layer has no projection metadata, falling back to EPSG:4326")
self.logger.info("Layer has no projection metadata, falling back to EPSG:4326")
if not self.gisorder:
spatial_ref = osr.SpatialReference()
spatial_ref.ImportFromEPSG(4326)
Expand Down Expand Up @@ -146,7 +152,7 @@ def get_layer(self, index):
layer = self.datasource.ExecuteSQL(self.query)
layer.ResetReading()
else:
logging.error("Query must be set first when the datasource is a database.")
self.logger.error("Query must be set first when the datasource is a database.")
else:
layer = self.datasource.GetLayer(index)
layer.ResetReading()
Expand Down
13 changes: 8 additions & 5 deletions ogr2osm/osm_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
from osgeo import ogr
from osgeo import osr

from .version import __program__
from .osm_geometries import OsmBoundary, OsmNode, OsmWay, OsmRelation

class OsmData:
def __init__(self, translation, rounding_digits=7, max_points_in_way=1800, add_bounds=False):
self.logger = logging.getLogger(__program__)

# options
self.translation = translation
self.rounding_digits = rounding_digits
Expand Down Expand Up @@ -204,7 +207,7 @@ def __parse_polygon_members(self, ogrgeometry, potential_duplicate_relations, fi
# relation is unique
potential_duplicate_relations.clear()
else:
logging.warning("Polygon with no exterior ring?")
self.logger.warning("Polygon with no exterior ring?")
return None

# interior rings
Expand Down Expand Up @@ -242,7 +245,7 @@ def __parse_polygon(self, ogrgeometry, tags):
# Special case polygons with only one ring. This does not (or at least
# should not) change behavior when simplify relations is turned on.
if ogrgeometry.GetGeometryCount() == 0:
logging.warning("Polygon with no rings?")
self.logger.warning("Polygon with no rings?")
return None
elif ogrgeometry.GetGeometryCount() == 1 and \
ogrgeometry.GetGeometryRef(0).GetPointCount() <= self.max_points_in_way:
Expand Down Expand Up @@ -289,7 +292,7 @@ def __parse_collection(self, ogrgeometry, tags):
not any(members)))
else:
# no support for nested collections or other unsupported types
logging.warning("Unhandled geometry in collection, type %d", geometry_type)
self.logger.warning("Unhandled geometry in collection, type %d", geometry_type)

if len(members) == 1 and len(members[0].nodes) <= self.max_points_in_way:
# only 1 polygon with 1 outer ring
Expand Down Expand Up @@ -325,7 +328,7 @@ def __parse_geometry(self, ogrgeometry, tags):
elif geometry_type in [ ogr.wkbGeometryCollection, ogr.wkbGeometryCollection25D ]:
osmgeometries.append(self.__parse_collection(ogrgeometry, tags))
else:
logging.warning("Unhandled geometry, type %d", geometry_type)
self.logger.warning("Unhandled geometry, type %d", geometry_type)

return osmgeometries

Expand Down Expand Up @@ -383,7 +386,7 @@ def split_long_ways(self):
# pointless :-)
return

logging.debug("Splitting long ways")
self.logger.debug("Splitting long ways")

for way in self.__ways:
if len(way.nodes) > self.max_points_in_way:
Expand Down
16 changes: 10 additions & 6 deletions ogr2osm/osm_datawriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@
accompany any distribution of this code.
'''

import logging, time
import logging
import time

from .version import __program__
from .datawriter_base_class import DataWriterBase

class OsmDataWriter(DataWriterBase):
def __init__(self, filename, never_upload=False, no_upload_false=False, never_download=False, \
locked=False, add_version=False, add_timestamp=False, significant_digits=9, \
suppress_empty_tags=False):
self.logger = logging.getLogger(__program__)

self.filename = filename
self.never_upload = never_upload
self.no_upload_false = no_upload_false
Expand Down Expand Up @@ -45,7 +49,7 @@ def open(self):


def write_header(self, bounds):
logging.debug("Writing file header")
self.logger.debug("Writing file header")

self.f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
self.f.write('<osm version="0.6" generator="ogr2osm %s"' % self.get_version())
Expand Down Expand Up @@ -73,22 +77,22 @@ def __write_geometries(self, geoms):


def write_nodes(self, nodes):
logging.debug("Writing nodes")
self.logger.debug("Writing nodes")
self.__write_geometries(nodes)


def write_ways(self, ways):
logging.debug("Writing ways")
self.logger.debug("Writing ways")
self.__write_geometries(ways)


def write_relations(self, relations):
logging.debug("Writing relations")
self.logger.debug("Writing relations")
self.__write_geometries(relations)


def write_footer(self):
logging.debug("Writing file footer")
self.logger.debug("Writing file footer")
self.f.write('</osm>')


Expand Down
12 changes: 8 additions & 4 deletions ogr2osm/osm_geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import logging
from lxml import etree

from .version import __program__

class OsmId:
element_id_counter = 0
element_id_counter_incr = -1
Expand All @@ -25,18 +27,20 @@ def set_id(start_id, is_positive = False):

@staticmethod
def load_id(filename):
logger = logging.getLogger(__program__)
with open(filename, 'r') as ff:
OsmId.element_id_counter = int(ff.readline(20))
logging.info("Starting counter value '%d' read from file '%s'.", \
OsmId.element_id_counter, filename)
logger.info("Starting counter value '%d' read from file '%s'.", \
OsmId.element_id_counter, filename)


@staticmethod
def save_id(filename):
logger = logging.getLogger(__program__)
with open(filename, 'w') as ff:
ff.write(str(OsmId.element_id_counter))
logging.info("Wrote elementIdCounter '%d' to file '%s'", \
OsmId.element_id_counter, filename)
logger.info("Wrote elementIdCounter '%d' to file '%s'", \
OsmId.element_id_counter, filename)



Expand Down

0 comments on commit a9965a7

Please sign in to comment.