Skip to content

Commit 10ea1b8

Browse files
committed
Merge branch 'master' into branch-0.11
Conflicts: CHANGELOG.creole pgmapcss/version.py
2 parents 36b0ae1 + 3cd21cc commit 10ea1b8

File tree

11 files changed

+109
-22
lines changed

11 files changed

+109
-22
lines changed

CHANGELOG.creole

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
0.11 release upcoming
22
* Mode standalone: specify ID or list of IDs instead of a bounding box
33
4+
0.10.5 release 2015-05-05
5+
* DB/Overpass: download from API in blocks, to avoid huge memory consumption. specify {{{db.overpass-blocksize}}} (default: 64MB).
6+
* Icon handling from 0.10.4 also for ol4pgm
7+
* Update Maki icons
8+
49
0.10.4 release 2015-03-11
510
* DB/Overpass: set max allowed memory by config option {{{db.overpass-memory}}}
611
* DB/Overpass: load full response at once; this greatly improves performance, but needs more memory.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Alternatively there's a standalone mode, where the MapCSS style is compiled into
1010

1111
Since version 0.10 you don't even need a local database import (a local database is needed nonetheless), as the new default data source is Overpass API. Alternatively, osm2pgsql and osmosis pgsnapshot are supported. See [doc/database.md](doc/database.md) for details.
1212

13-
Stable version: [0.10.4](https://github.com/plepe/pgmapcss) ([CHANGELOG](https://github.com/plepe/pgmapcss/blob/master/CHANGELOG.creole)), development versions: [0.11-dev](https://github.com/plepe/pgmapcss/tree/branch-0.11) ([open issues](https://github.com/plepe/pgmapcss/milestones/Version%200.11)) resp. [NG-dev](https://github.com/plepe/pgmapcss/tree/pgmapcss-NG)([open issues](https://github.com/plepe/pgmapcss/milestones/pgmapcss%20NG)).
13+
Stable version: [0.10.5](https://github.com/plepe/pgmapcss) ([CHANGELOG](https://github.com/plepe/pgmapcss/blob/master/CHANGELOG.creole)), development versions: [0.11-dev](https://github.com/plepe/pgmapcss/tree/branch-0.11) ([open issues](https://github.com/plepe/pgmapcss/milestones/Version%200.11)) resp. [NG-dev](https://github.com/plepe/pgmapcss/tree/pgmapcss-NG)([open issues](https://github.com/plepe/pgmapcss/milestones/pgmapcss%20NG)).
1414

1515
Features
1616
--------

doc/config_options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ Advances options:
3333
| db.overpass-timeout | overpass only: specify timeout in seconds for queries to the Overpass API (make sure that the Overpass server accepts timeouts that long, e.g. by adding a "Timeout" parameter to Apache2). As a render job usually needs several queries, the total rendering time might be a multiple of this value. | 180
3434
| db.overpass-memory | overpass only: Sets the 'maxsize' parameter for an overpass query, which indicates the maximum allowed memory for the query in bytes RAM on the server. | 536870912 (512 MB)
3535
| db.overpass-profiler | overpass only: prints all queries, their duration (incl. parsing json) and the count of returned features. | true/**false**
36+
| db.overpass-blocksize | overpass only: When reading from Overpass API read in blocks of specified size. Reduces memory impact. | 67108864 (64 MB)

doc/database.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Behaviour can be influenced with the following config options:
3030
| db.overpass-timeout | specify timeout in seconds for queries to the Overpass API (make sure that the Overpass server accepts timeouts that long, e.g. by adding a "Timeout" parameter to Apache2). As a render job usually needs several queries, the total rendering time might be a multiple of this value. | 180
3131
| db.overpass-memory | Sets the 'maxsize' parameter for an overpass query, which indicates the maximum allowed memory for the query in bytes RAM on the server. | 536870912 (512 MB)
3232
| db.overpass-profiler | overpass only: prints all queries, their duration (incl. parsing json) and the count of returned features. | true/**false**
33+
| db.overpass-blocksize | overpass only: When reading from Overpass API read in blocks of specified size. Reduces memory impact. | 67108864 (64 MB)
3334

3435
Example usage:
3536
```sh

pgmapcss/db/overpass/db.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ def __init__(self, conn, stat):
1919
if not 'db.overpass-memory' in self.stat['config']:
2020
self.stat['config']['db.overpass-memory'] = '536870912'
2121

22+
if not 'db.overpass-blocksize' in self.stat['config']:
23+
self.stat['config']['db.overpass-blocksize'] = '67108864'
24+
2225
self.parent_queries = []
2326

2427
def tag_type(self, key, condition):

pgmapcss/db/overpass/db_functions.py

Lines changed: 93 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,120 @@ def overpass_query(query):
77

88
# START db.overpass-profiler
99
time_start = datetime.datetime.now()
10+
time_duration = datetime.timedelta(0)
11+
download_size = 0
12+
count = 0
13+
count_blocks = 0
1014
# END db.overpass-profiler
1115
url = '{db.overpass-url}/interpreter'
1216
data = urllib.parse.urlencode({ 'data': query })
1317
data = data.encode('utf-8')
14-
count = 0
1518

1619
try:
1720
f = urllib.request.urlopen(url, data)
1821
except urllib.error.HTTPError as err:
1922
plpy.warning('Overpass query failed:\n' + query)
2023
raise
2124

22-
try:
23-
r = f.read().decode('utf-8')
24-
except urllib.error.HTTPError as err:
25-
plpy.warning('Overpass query failed (after {} features):\n'.format(count) + query)
26-
raise
25+
first = True
26+
done = False
27+
to_parse = None
28+
result = None
29+
block_remains = ''
2730

28-
# areas not initialized -> ignore
29-
if re.search('osm3s_v[0-9\.]+_areas', r):
30-
f.close()
31-
return
31+
while not done:
32+
# START db.overpass-profiler
33+
count_blocks += 1
34+
# END db.overpass-profiler
35+
try:
36+
r = f.read({db.overpass-blocksize})
37+
# START db.overpass-profiler
38+
download_size += len(r)
39+
# END db.overpass-profiler
3240

33-
data = json.loads(r)
41+
# make sure that result is valid UTF-8
42+
# thanks to http://rosettacode.org/wiki/Read_a_file_character_by_character/UTF8#Python
43+
while True:
44+
try:
45+
r = r.decode('utf-8')
46+
except UnicodeDecodeError:
47+
r += f.read(1)
48+
# START db.overpass-profiler
49+
download_size += 1
50+
# END db.overpass-profiler
51+
else:
52+
break
53+
except urllib.error.HTTPError as err:
54+
plpy.warning('Overpass query failed (after {} features):\n'.format(count) + query)
55+
raise
56+
57+
# EOF detected
58+
if not r:
59+
done = True
60+
61+
# areas not initialized -> ignore
62+
if first and re.search('osm3s_v[0-9\.]+_areas', r):
63+
f.close()
64+
return
65+
66+
if first:
67+
# maybe we could read whole result in blocksize
68+
first = False
69+
try:
70+
result = json.loads(r)
71+
except ValueError:
72+
pass
73+
else:
74+
done = True
3475

35-
if 'remark' in data:
76+
# try to read complete elements from block, remember surroundings for
77+
# later (block_remains)
78+
if done:
79+
to_parse = block_remains
80+
else:
81+
block_remains += r
82+
end_last = block_remains.rfind('\n},')
83+
if end_last != -1:
84+
start = block_remains.find('"elements": [')
85+
to_parse = block_remains[0 : end_last] + '}]\n}'
86+
block_remains = block_remains[0 : start + 13] + block_remains[end_last + 3 :]
87+
88+
# try to load JSON - if not complete, try after next reading
89+
if to_parse:
90+
try:
91+
result = json.loads(to_parse)
92+
to_parse = None
93+
except ValueError:
94+
pass
95+
96+
# START db.overpass-profiler
97+
time_duration += (datetime.datetime.now() - time_start)
98+
# END db.overpass-profiler
99+
100+
# found a result
101+
if result:
102+
# START db.overpass-profiler
103+
count += len(result['elements'])
104+
# END db.overpass-profiler
105+
for e in result['elements']:
106+
yield e
107+
result['elements'] = []
108+
109+
# START db.overpass-profiler
110+
time_start = datetime.datetime.now()
111+
# END db.overpass-profiler
112+
113+
if 'remark' in result:
36114
# ignore timeout if it happens in "print"
37115
if not re.search("Query timed out in \"print\"", data['remark']):
38116
raise Exception('Error in Overpass API (after {} features): {}\nFailed query was:\n{}'.format(count, data['remark'], query))
39117

118+
f.close()
119+
40120
# START db.overpass-profiler
41-
plpy.warning('%s\nquery took %.2fs for %d features' % (query, (datetime.datetime.now() - time_start).total_seconds(), len(data['elements'])))
121+
plpy.warning('%s\nquery took %.2fs for %d features (%.1f MB, %d blocks)' % (query, time_duration.total_seconds(), count, download_size / 1024.0 / 1024, count_blocks))
42122
# END db.overpass-profiler
43123

44-
for e in data['elements']:
45-
yield e
46-
47124
def node_geom(lat, lon):
48125
global geom_plan
49126

pgmapcss/icons/maki/dentist-12.svg

Lines changed: 1 addition & 1 deletion
Loading

pgmapcss/icons/maki/dentist-18.svg

Lines changed: 1 addition & 1 deletion
Loading

pgmapcss/icons/maki/dentist-24.png

-395 Bytes
Loading

pgmapcss/icons/maki/dentist-24.svg

Lines changed: 1 addition & 1 deletion
Loading

0 commit comments

Comments
 (0)