source: subversion/applications/utils/true_offset/update_calibration.py @ 34747

Last change on this file since 34747 was 25946, checked in by plush, 8 years ago

Print the calibration area name at the top, not the bottom of diagnostic messages.

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 5.6 KB
Line 
1#!/usr/bin/env python
2
3"""True Offset Process update_calibration.py
4
5Copyright (c) 2011, Bartosz Fabianowski <bartosz@fabianowski.eu>
6All rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions are met:
10
11* Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13* Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16* Neither the name of the author nor the names of its contributors may be used
17  to endorse or promote products derived from this software without specific
18  prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31$Id: update_calibration.py 25946 2011-05-04 21:57:24Z donvip $
32"""
33import sys
34import urllib2
35import xml.parsers.expat
36
37import ppygis
38import psycopg2
39
40database = 'dbname=offset_production'
41xapi = 'http://open.mapquestapi.com/xapi/'
42
43dry_run = True
44
45reload(sys)
46sys.setdefaultencoding('utf-8')
47
48try:
49  connection = psycopg2.connect(database)
50  cursor = connection.cursor()
51except Exception, exception:
52  sys.exit('Unable to establish database connection: {0}'.format(exception))
53
54try:
55  offsets = urllib2.urlopen('{0}api/0.6/way[calibration=area]'.format(xapi))
56except Exception, exception:
57  sys.exit('Unable to retrieve offsets from XAPI: {0}'.format(exception))
58
59nodes = dict()
60id = None
61user = None
62boundary = ppygis.LineString([])
63tags = dict()
64
65def print_message(message, id, user, name, header='INFO'):
66  print header
67  if name:
68    print '  Area name:  {0}'.format(name)
69  print '  Reason:     {0}'.format(message)
70  print '  Way:        http://api.openstreetmap.org/api/0.6/way/{0}'.format(id)
71  print '  User:       http://www.openstreetmap.org/user/{0}'.format(user)
72  print
73
74def process_start(name, attributes):
75  global nodes, id, user, boundary, tags
76
77  if name == 'node':
78    nodes[attributes['id']] = ppygis.Point(float(attributes['lon']),
79                                           float(attributes['lat']))
80  elif name == 'way':
81    id = attributes['id']
82    user = attributes['user']
83    boundary = ppygis.LineString([])
84    tags = dict()
85  elif name == 'nd':
86    boundary.points.append(nodes[attributes['ref']])
87  elif name == 'tag':
88    tags[attributes['k']] = attributes['v']
89
90def process_end(name):
91  if name == 'way':
92    try:
93      name = tags['area_name'] if 'area_name' in tags else None
94      provider = tags['data_provider'] if 'data_provider' in tags else None
95      zoom_min = tags['zoom_min'] if 'zoom_min' in tags else None
96      zoom_max = tags['zoom_max'] if 'zoom_max' in tags else None
97      offset_north = tags['offset_north'] if 'offset_north' in tags else None
98      offset_east = tags['offset_east'] if 'offset_east' in tags else None
99
100      if name is None:
101        print_message('Recommended tag "area_name" missing', id, user, name)
102
103      if provider is None:
104        raise Exception('Required tag "data_provider" missing')
105
106      if zoom_min is not None and zoom_max is not None and zoom_min > zoom_max:
107        raise Exception('Invalid zoom range ("zoom_min" > "zoom_max")')
108
109      if offset_north and ',' in offset_north:
110        print_message('Tag "offset_north" uses comma as decimal separator', id,
111                      user, name)
112        offset_north = float(offset_north.replace(',', '.'))
113
114      if offset_east and ',' in offset_east:
115        print_message('Tag "offset_east" uses comma as decimal separator', id,
116                      user, name)
117        offset_east = float(offset_east.replace(',', '.'))
118
119      if offset_north is None and offset_east is None:
120        raise Exception('Neither tag "offset_north" nor tag "offset_east" ' +
121                        'specified')
122
123      offset_north = float(offset_north)
124      offset_east = float(offset_east)
125
126      if abs(offset_north) > 1.0:
127        raise Exception('Value of tag "offset_north" exceeds one degree')
128
129      if abs(offset_east) > 1.0:
130        raise Exception('Value of tag "offset_east" exceeds one degree')
131
132      try:
133        cursor.execute('INSERT INTO offsets(name, provider, zoom_min, ' +
134                       'zoom_max, offset_north, offset_east, boundary) ' +
135                       'VALUES (%s, %s, %s, %s, %s, %s, %s)',
136                       (name, provider, zoom_min, zoom_max, offset_north,
137                        offset_east, boundary))
138      except Exception, exception:
139        print_message(exception, id, user, name,
140                      'ERROR Entire import aborted due to SQL error')
141        sys.exit(1)
142
143    except Exception, exception:
144      print_message(exception, id, user, name,
145                    'WARNING Calibration area not imported')
146
147cursor.execute('DELETE FROM offsets')
148
149parser = xml.parsers.expat.ParserCreate()
150parser.StartElementHandler = process_start
151parser.EndElementHandler = process_end
152parser.ParseFile(offsets)
153
154if not dry_run:
155  connection.commit()
Note: See TracBrowser for help on using the repository browser.