mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-14 10:27:57 +00:00
Compare commits
213 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83ce6e12e7 | ||
|
|
5b4c7b7f7e | ||
|
|
70997a9554 | ||
|
|
805f16b0cd | ||
|
|
083c55b230 | ||
|
|
a24991b430 | ||
|
|
3b44edf4a5 | ||
|
|
8b75e1f4c4 | ||
|
|
a2994fc55c | ||
|
|
ebdd250fa0 | ||
|
|
676c565905 | ||
|
|
4d15bdaacc | ||
|
|
f9ee4e3bd3 | ||
|
|
c2112fc6ff | ||
|
|
8b491e8544 | ||
|
|
40588482a2 | ||
|
|
c2b68c337b | ||
|
|
a73135aebe | ||
|
|
634d04068d | ||
|
|
a5883337f5 | ||
|
|
21385f5e51 | ||
|
|
4cade95b24 | ||
|
|
a9b370fcb2 | ||
|
|
355d1efe21 | ||
|
|
620100a5ac | ||
|
|
cd37227a3c | ||
|
|
690d7014f8 | ||
|
|
ef1a7d9073 | ||
|
|
8f0199008d | ||
|
|
9f1d3ac272 | ||
|
|
513efecc34 | ||
|
|
6822e50fe5 | ||
|
|
248588fbf3 | ||
|
|
f01828ae02 | ||
|
|
47a7887d86 | ||
|
|
016815eda2 | ||
|
|
f2a2c29815 | ||
|
|
97c572b92f | ||
|
|
851af3db7f | ||
|
|
fc961c14fa | ||
|
|
91f3405713 | ||
|
|
645182f2c0 | ||
|
|
e0e812d09b | ||
|
|
7e8e952b66 | ||
|
|
32c8dabefe | ||
|
|
b079b4713f | ||
|
|
baefb4062f | ||
|
|
af150bc63e | ||
|
|
fb7d65b8c3 | ||
|
|
dbb1f5c0e2 | ||
|
|
2e1281b9a0 | ||
|
|
2338d04e9f | ||
|
|
111444cd99 | ||
|
|
10a965c3ab | ||
|
|
fc9e75a5e6 | ||
|
|
347f8e57c7 | ||
|
|
f24b904f9a | ||
|
|
0df8a4e24f | ||
|
|
ccca38f22d | ||
|
|
b2cca7cea1 | ||
|
|
b5c9845448 | ||
|
|
9fb2bf36be | ||
|
|
5cc1946dfc | ||
|
|
fe3eb40e3a | ||
|
|
7822b1bc25 | ||
|
|
5b1eca4c48 | ||
|
|
8375392f39 | ||
|
|
71ab123fbb | ||
|
|
c7eea2e419 | ||
|
|
b0d9c0598e | ||
|
|
1e4c22a037 | ||
|
|
ce49d3c632 | ||
|
|
6479768932 | ||
|
|
5c187182a3 | ||
|
|
c242386ddb | ||
|
|
c9d7015f69 | ||
|
|
e90087a063 | ||
|
|
058f597186 | ||
|
|
95a681f128 | ||
|
|
ddb2b3cafb | ||
|
|
a1f3bfb35a | ||
|
|
86ca377b1a | ||
|
|
5581bb67f8 | ||
|
|
9e5c9ca81d | ||
|
|
134553b184 | ||
|
|
dbabfcd0cf | ||
|
|
b328bcf518 | ||
|
|
3fe49072fe | ||
|
|
9b7d8db038 | ||
|
|
df7d3b7478 | ||
|
|
d7c3f04e04 | ||
|
|
23a53661e0 | ||
|
|
86e946d369 | ||
|
|
8c656fb667 | ||
|
|
7c8c206818 | ||
|
|
1fcb712f00 | ||
|
|
80df4d3b56 | ||
|
|
b4f9252c63 | ||
|
|
3e871d6ee0 | ||
|
|
dd97528726 | ||
|
|
c51ca976ed | ||
|
|
c1f65ba7cf | ||
|
|
bf77c72195 | ||
|
|
3257c04d94 | ||
|
|
ddb2e4aa12 | ||
|
|
2f8a29ba39 | ||
|
|
4ba93dcb50 | ||
|
|
68596436b1 | ||
|
|
79f1107391 | ||
|
|
3b809c40f1 | ||
|
|
3134fb8b40 | ||
|
|
48e0b318f2 | ||
|
|
6727c36298 | ||
|
|
a97808afec | ||
|
|
cf36e8d2fb | ||
|
|
cc40706188 | ||
|
|
a7e1b3b1ee | ||
|
|
46e64bd933 | ||
|
|
2e1590ed89 | ||
|
|
27753fb8db | ||
|
|
2a3672c19b | ||
|
|
9746629fd3 | ||
|
|
b7fd7ef169 | ||
|
|
ab47773604 | ||
|
|
07cbf1535b | ||
|
|
5eb56c11ba | ||
|
|
b82c8ceab9 | ||
|
|
a5a0e1dd0b | ||
|
|
ddcb95ca39 | ||
|
|
4a3dc3187c | ||
|
|
133dd2e974 | ||
|
|
eb1d8894b9 | ||
|
|
59be7846e9 | ||
|
|
aaabf70a1c | ||
|
|
987b6a70c9 | ||
|
|
2bcd1aa194 | ||
|
|
86b4df1e81 | ||
|
|
753227ae25 | ||
|
|
ef48ee5f80 | ||
|
|
0930f6e728 | ||
|
|
6f98fa0fb3 | ||
|
|
555362eabe | ||
|
|
9f4c7f4e6d | ||
|
|
1eb52879c6 | ||
|
|
27ce2afbcf | ||
|
|
9d9745b378 | ||
|
|
30f087b168 | ||
|
|
1ce3307b7a | ||
|
|
a25810d317 | ||
|
|
394a00f521 | ||
|
|
9e3e7bf791 | ||
|
|
6dcdf34fda | ||
|
|
f4d7337266 | ||
|
|
7ed580f1d5 | ||
|
|
c6d8e91b88 | ||
|
|
340b9793d6 | ||
|
|
82e5a95f16 | ||
|
|
822ca14480 | ||
|
|
b41a5c962c | ||
|
|
3c2c3ab674 | ||
|
|
2b2b6ffadc | ||
|
|
02cd91d251 | ||
|
|
5d87136969 | ||
|
|
0de6f37647 | ||
|
|
c9f3d7d08b | ||
|
|
62ed8b9e0c | ||
|
|
cf5ced6618 | ||
|
|
0f84371748 | ||
|
|
43b925b258 | ||
|
|
b145dadd63 | ||
|
|
7769b0a823 | ||
|
|
330f147b02 | ||
|
|
fbc5ba13f8 | ||
|
|
c798577f70 | ||
|
|
4c2fa68c55 | ||
|
|
d1552b0904 | ||
|
|
b121da0ca3 | ||
|
|
f6bfadaef6 | ||
|
|
b9355ac829 | ||
|
|
f54ad3b86d | ||
|
|
e16fcf879d | ||
|
|
021702f190 | ||
|
|
138b8a2ada | ||
|
|
352f0fdc27 | ||
|
|
8c89b65082 | ||
|
|
f156da6b63 | ||
|
|
759222eef2 | ||
|
|
14d17a3ad4 | ||
|
|
6d0ab44800 | ||
|
|
a855bfc6e5 | ||
|
|
3db64e7913 | ||
|
|
d6e7bbaad9 | ||
|
|
1217083146 | ||
|
|
635006b19b | ||
|
|
c391479c58 | ||
|
|
04a20a2a0a | ||
|
|
6382b1c111 | ||
|
|
59de7c5a9b | ||
|
|
4b8632d1e5 | ||
|
|
8f09b9378f | ||
|
|
e1c88352ab | ||
|
|
084a110efb | ||
|
|
52265a33ba | ||
|
|
475108b937 | ||
|
|
02c219d40e | ||
|
|
4cfeeb06ba | ||
|
|
dd18e74079 | ||
|
|
e62ae5b090 | ||
|
|
8989776bfd | ||
|
|
d899b3b04c | ||
|
|
2d6f00945a | ||
|
|
6a22d71b3b | ||
|
|
d794b74550 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,6 +16,7 @@ autom4te.cache/
|
||||
config.*
|
||||
configure
|
||||
Makefile
|
||||
!tests/scenes/bin/Makefile
|
||||
Makefile.in
|
||||
stamp-h1
|
||||
missing
|
||||
@@ -29,3 +30,4 @@ data/wiki_import.sql
|
||||
data/wiki_specialphrases.sql
|
||||
data/osmosischange.osc
|
||||
|
||||
.vagrant
|
||||
2
AUTHORS
2
AUTHORS
@@ -15,3 +15,5 @@ Nominatim was written by:
|
||||
Kurt Roeckx
|
||||
Rodolphe Quiédeville
|
||||
Marc Tobias Metten
|
||||
|
||||
Reverse geocoding using Tiger data feature made possible with support from Guru Labs
|
||||
|
||||
91
ChangeLog
91
ChangeLog
@@ -1,7 +1,60 @@
|
||||
2.0.1
|
||||
2.5.1
|
||||
|
||||
* delete outdated entries from location_area_country
|
||||
* remove remaining uses of INTEGER, to allow node ids larger than 2^31
|
||||
* fix layout error in details page when keywords are displayed
|
||||
* fix website check during setup
|
||||
|
||||
2.5
|
||||
|
||||
* reverse geocoding includes looking up housenumbers from Tiger data
|
||||
* added parameter to return simplified geometries
|
||||
* new lookup call for getting address information for OSM objects
|
||||
* new namedetails and extratags parameters that expose the name and extratags
|
||||
fields of the placex table
|
||||
* mobile website
|
||||
* reverse web view
|
||||
|
||||
2.4
|
||||
|
||||
* drop support for postgres 8.4
|
||||
* rewrite address interpolation
|
||||
* switch to C++ version of osm2pgsql and rewrite tag filtering
|
||||
* support for bridge:name and tunnel:name, man_made, junction
|
||||
* drop way-node index (reduces database size by about 15%)
|
||||
* add support for configuring tablespaces and webserver user
|
||||
* better evaluation of search queries in right-to-left notation
|
||||
* improve house number search for streets with many duplicate entries
|
||||
* code cleanup (remove unused functions and tables)
|
||||
|
||||
2.3
|
||||
|
||||
* further improve ordering of results
|
||||
* support for more lat/lon formats in search-as-reverse
|
||||
* fix handling of GB postcodes
|
||||
* new functional test suite
|
||||
* support for waterway relations
|
||||
* inherit postcodes from street to poi
|
||||
* fix housenumber normalisation to find non-latin house numbers
|
||||
* take viewbox into account for ordering of results
|
||||
* pois may now inherit address tags from surrounding buildings
|
||||
* improve what objects may participate in an address
|
||||
* clean up handled class/type combinations to current OSM usage
|
||||
* lots of bug fixes
|
||||
|
||||
2.2
|
||||
|
||||
* correct database rights for www-data
|
||||
* add timestamps for update output
|
||||
* load postgis via extension for postgis >= 2.0
|
||||
* remove non-admin boundaries from addresses
|
||||
* further improve ordering of results with same importance
|
||||
* merge addr:postcode tags into object addresses
|
||||
* include rank and importance in reverse geocode output
|
||||
* replace ST_Line_Interpolate_Point with ST_LineInterpolatePoint
|
||||
(for postgis >= 2.1)
|
||||
* update osm2pgsql to latest version
|
||||
* properly detect changes of admin_level
|
||||
* remove landuses when name is removed
|
||||
* smaller fixes
|
||||
|
||||
2.1
|
||||
|
||||
@@ -27,33 +80,7 @@
|
||||
* refactoring of front-end PHP code
|
||||
* lots of smaller bug fixes
|
||||
|
||||
2.2
|
||||
2.0.1
|
||||
|
||||
* correct database rights for www-data
|
||||
* add timestamps for update output
|
||||
* load postgis via extension for postgis >= 2.0
|
||||
* remove non-admin boundaries from addresses
|
||||
* further improve ordering of results with same importance
|
||||
* merge addr:postcode tags into object addresses
|
||||
* include rank and importance in reverse geocode output
|
||||
* replace ST_Line_Interpolate_Point with ST_LineInterpolatePoint
|
||||
(for postgis >= 2.1)
|
||||
* update osm2pgsql to latest version
|
||||
* properly detect changes of admin_level
|
||||
* remove landuses when name is removed
|
||||
* smaller fixes
|
||||
|
||||
2.3
|
||||
|
||||
* further improve ordering of results
|
||||
* support for more lat/lon formats in search-as-reverse
|
||||
* fix handling of GB postcodes
|
||||
* new functional test suite
|
||||
* support for waterway relations
|
||||
* inherit postcodes from street to poi
|
||||
* fix housenumber normalisation to find non-latin house numbers
|
||||
* take viewbox into account for ordering of results
|
||||
* pois may now inherit address tags from surrounding buildings
|
||||
* improve what objects may participate in an address
|
||||
* clean up handled class/type combinations to current OSM usage
|
||||
* lots of bug fixes
|
||||
* delete outdated entries from location_area_country
|
||||
* remove remaining uses of INTEGER, to allow node ids larger than 2^31
|
||||
|
||||
5
README
5
README
@@ -24,6 +24,9 @@ how to set up your own instance of Nominatim can be found in the wiki:
|
||||
|
||||
http://wiki.openstreetmap.org/wiki/Nominatim/Installation
|
||||
|
||||
Note that this repository contains a submodule called osm2pgsql. Make sure it
|
||||
is cloned as well by running `git submodule update --init`.
|
||||
|
||||
Installation steps:
|
||||
|
||||
0. If checking out from git run:
|
||||
@@ -32,7 +35,7 @@ Installation steps:
|
||||
|
||||
1. Compile Nominatim:
|
||||
|
||||
./configure [--enable-64bit-ids]
|
||||
./configure
|
||||
make
|
||||
|
||||
2. Get OSM data and import:
|
||||
|
||||
172
VAGRANT.md
Normal file
172
VAGRANT.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Install Nominatim in a virtual machine for development and testing
|
||||
|
||||
This document describes how you can install Nominatim inside a Ubuntu 14
|
||||
virtual machine on your desktop/laptop (host machine). The goal is to give
|
||||
you a development environment to easily edit code and run the test suite
|
||||
without affecting the rest of your system.
|
||||
|
||||
The installation can run largely unsupervised. You should expect 1-2h from
|
||||
start to finish depending on how fast your computer and download speed
|
||||
is.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. [Virtualbox](https://www.virtualbox.org/wiki/Downloads)
|
||||
|
||||
2. [Vagrant](https://www.vagrantup.com/downloads.html)
|
||||
|
||||
3. Nominatim
|
||||
|
||||
git clone --recursive https://github.com/twain47/Nominatim.git
|
||||
|
||||
If you haven't used `--recursive`, then you can load the submodules using
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
1. Start the virtual machine
|
||||
|
||||
vagrant up ubuntu
|
||||
|
||||
2. Log into the virtual machine
|
||||
|
||||
vagrant ssh ubuntu
|
||||
|
||||
3. Import a small country (Monaco)
|
||||
|
||||
You need to give the virtual machine more memory (2GB) for an import,
|
||||
see `Vagrantfile`. Otherwise 1GB is enough.
|
||||
|
||||
See the FAQ how to skip this step and point Nominatim to an existing database.
|
||||
|
||||
```
|
||||
# inside the virtual machine:
|
||||
cd Nominatim
|
||||
wget --no-verbose --output-document=data/monaco.osm.pbf http://download.geofabrik.de/europe/monaco-latest.osm.pbf
|
||||
./utils/setup.php --osm-file data/monaco.osm.pbf --osm2pgsql-cache 1000 --all 2>&1 | tee monaco.$$.log
|
||||
./utils/specialphrases.php --countries > data/specialphrases_countries.sql
|
||||
psql -d nominatim -f data/specialphrases_countries.sql
|
||||
```
|
||||
|
||||
To repeat an import you'd need to delete the database first
|
||||
|
||||
dropdb -if-exists nominatim
|
||||
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Vagrant maps the virtual machine's port 8089 to your host machine. Thus you can
|
||||
see Nominatim in action on [locahost:8089](http://localhost:8089/nominatim/).
|
||||
|
||||
You edit code on your host machine in any editor you like. There is no need to
|
||||
restart any software: just refresh your browser window.
|
||||
|
||||
PHP errors are written to `/var/log/apache2/error.log`.
|
||||
|
||||
With `echo` and `var_dump()` you write into the output (HTML/XML/JSON) when
|
||||
you either add `&debug=1` to the URL (preferred) or set
|
||||
`@define('CONST_Debug', true);` in `settings/local.php`.
|
||||
|
||||
|
||||
|
||||
|
||||
## Running functional tests
|
||||
|
||||
Tests in `/features/db` and `/features/osm2pgsql` have to pass 100%. Other
|
||||
tests might require full planet-wide data. Sadly even if you have your own
|
||||
planet-wide data there will be enough differences to the openstreetmap.org
|
||||
installation to cause false positives in the other tests (see FAQ).
|
||||
|
||||
To run the full test suite
|
||||
|
||||
cd ~/Nominatim/tests
|
||||
NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce features
|
||||
|
||||
To run a single file
|
||||
|
||||
NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce features/api/reverse.feature
|
||||
|
||||
To run specific tests you can add tags just before the `Scenario line`, e.g.
|
||||
|
||||
@bug-34
|
||||
Scenario: address lookup for non-existing or invalid node, way, relation
|
||||
|
||||
and then
|
||||
|
||||
NOMINATIM_SERVER=http://localhost:8089/nominatim lettuce -t bug-34
|
||||
|
||||
|
||||
## Running unit tests
|
||||
|
||||
cd ~/Nominatim/tests-php
|
||||
phpunit ./
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
##### Will it run on Windows?
|
||||
|
||||
Yes, Vagrant and Virtualbox can be installed on MS Windows just fine. You need a 64bit
|
||||
version of Windows.
|
||||
|
||||
|
||||
##### Why Monaco, can I use another country?
|
||||
|
||||
Of course! The Monaco import takes less than 30 minutes and works with 2GB RAM.
|
||||
|
||||
##### Will the results be the same as those from nominatim.openstreetmap.org?
|
||||
|
||||
No. Long running Nominatim installations will differ once new import features (or
|
||||
bug fixes) get added since those usually only get applied to new/changed data.
|
||||
|
||||
Also this document skips the optional Wikipedia data import which affects ranking
|
||||
of search results. See [Nominatim installation](http://wiki.openstreetmap.org/wiki/Nominatim/Installation) for details.
|
||||
|
||||
##### Why Ubuntu and CentOS, can I test CentOS/CoreOS/FreeBSD?
|
||||
|
||||
There is a Vagrant script for CentOS available. Simply start your box
|
||||
with `vagrant up centos` and then log in with `vagrant ssh centos`.
|
||||
In general Nominatim will also run in the other environments. The installation steps
|
||||
are slightly different, e.g. the name of the package manager, Apache2 package
|
||||
name, location of files. We chose Ubuntu because that is closest to the
|
||||
nominatim.openstreetmap.org production environment.
|
||||
|
||||
You can configure/download other Vagrant boxes from [vagrantbox.es](http://www.vagrantbox.es/).
|
||||
|
||||
|
||||
##### How can I connect to an existing database?
|
||||
|
||||
Let's say you have a Postgres database named `nominatim_it` on server `your-server.com` and port `5432`. The Postgres username is `postgres`. You can edit `settings/local.php` and point Nominatim to it.
|
||||
|
||||
pgsql://postgres@your-server.com:5432/nominatim_it
|
||||
|
||||
No data import necessary, no restarting necessary.
|
||||
|
||||
If the Postgres installation is behind a firewall, you can try
|
||||
|
||||
ssh -L 9999:localhost:5432 your-username@your-server.com
|
||||
|
||||
inside the virtual machine. It will map the port to `localhost:9999` and then
|
||||
you edit `settings/local.php` with
|
||||
|
||||
pgsql://postgres@localhost:9999/nominatim_it
|
||||
|
||||
To access postgres directly remember to specify the hostname, e.g. `psql --host localhost --port 9999 nominatim_it`
|
||||
|
||||
|
||||
##### My computer is slow and the import takes too long. Can I start the virtual machine "in the cloud"?
|
||||
|
||||
Yes. It's possible to start the virtual machine on [Amazon AWS (plugin)](https://github.com/mitchellh/vagrant-aws) or [DigitalOcean (plugin)](https://github.com/smdahlen/vagrant-digitalocean).
|
||||
|
||||
|
||||
|
||||
|
||||
47
Vagrantfile
vendored
Normal file
47
Vagrantfile
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
Vagrant.configure("2") do |config|
|
||||
# Apache webserver
|
||||
config.vm.network "forwarded_port", guest: 8089, host: 8089
|
||||
|
||||
# If true, then any SSH connections made will enable agent forwarding.
|
||||
config.ssh.forward_agent = true
|
||||
|
||||
config.vm.synced_folder ".", "/home/vagrant/Nominatim"
|
||||
|
||||
config.vm.define "ubuntu" do |sub|
|
||||
sub.vm.box = "ubuntu/trusty64"
|
||||
sub.vm.provision :shell, :path => "vagrant/ubuntu-trusty-provision.sh"
|
||||
end
|
||||
config.vm.define "centos" do |sub|
|
||||
sub.vm.box = "bento/centos-7.2"
|
||||
sub.vm.provision :shell, :path => "vagrant/centos-7-provision.sh"
|
||||
end
|
||||
|
||||
# configure shared package cache if possible
|
||||
#if Vagrant.has_plugin?("vagrant-cachier")
|
||||
# config.cache.enable :apt
|
||||
# config.cache.scope = :box
|
||||
#end
|
||||
|
||||
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
vb.gui = false
|
||||
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
||||
end
|
||||
|
||||
|
||||
# config.vm.provider :digital_ocean do |provider, override|
|
||||
# override.ssh.private_key_path = '~/.ssh/id_rsa'
|
||||
# override.vm.box = 'digital_ocean'
|
||||
# override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
|
||||
|
||||
# provider.token = ''
|
||||
# # provider.token = 'YOUR TOKEN'
|
||||
# provider.image = 'ubuntu-14-04-x64'
|
||||
# provider.region = 'nyc2'
|
||||
# provider.size = '512mb'
|
||||
# end
|
||||
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
AC_INIT(Nominatim,2.2)
|
||||
AC_INIT(Nominatim,2.5.1)
|
||||
if git rev-parse HEAD 2>/dev/null >/dev/null; then
|
||||
AC_SUBST([PACKAGE_VERSION], [$PACKAGE_VERSION-git-`git rev-parse --short HEAD`])
|
||||
fi
|
||||
@@ -9,6 +9,7 @@ AC_PREREQ(2.61)
|
||||
AM_INIT_AUTOMAKE([1.9.6 dist-bzip2 std-options check-news])
|
||||
|
||||
dnl Additional macro definitions are in here
|
||||
m4_include([m4/ax_lib_postgresql_svr.m4])
|
||||
AC_CONFIG_MACRO_DIR([osm2pgsql/m4])
|
||||
|
||||
dnl Generate configuration header file
|
||||
@@ -40,11 +41,12 @@ fi
|
||||
|
||||
|
||||
dnl Check for PostgresSQL client library
|
||||
AX_LIB_POSTGRESQL(8.4)
|
||||
AX_LIB_POSTGRESQL(9.0)
|
||||
if test "x$POSTGRESQL_VERSION" = "x"
|
||||
then
|
||||
AC_MSG_ERROR([postgresql client library not found])
|
||||
fi
|
||||
AX_LIB_POSTGRESQL_SVR(9.0)
|
||||
if test ! -f "$POSTGRESQL_PGXS"
|
||||
then
|
||||
AC_MSG_ERROR([postgresql server development library not found])
|
||||
|
||||
@@ -295,7 +295,6 @@ CREATE INDEX idx_country_name_country_code ON country_name USING btree (country_
|
||||
--
|
||||
|
||||
REVOKE ALL ON TABLE country_name FROM PUBLIC;
|
||||
GRANT SELECT ON TABLE country_name TO "www-data";
|
||||
|
||||
|
||||
--
|
||||
|
||||
@@ -24,4 +24,3 @@ CREATE TABLE gb_postcode (
|
||||
CONSTRAINT enforce_srid_geometry CHECK ((st_srid(geometry) = 4326))
|
||||
);
|
||||
|
||||
GRANT SELECT ON TABLE gb_postcode TO "www-data";
|
||||
|
||||
@@ -49637,7 +49637,7 @@ kein 100
|
||||
|
||||
select count(make_keywords(v)) from (select distinct svals(name) as v from place) as w where v is not null;
|
||||
select count(make_keywords(v)) from (select distinct postcode as v from place) as w where v is not null;
|
||||
select count(getorcreate_housenumber_id(v)) from (select distinct housenumber as v from place where housenumber is not null) as w;
|
||||
select count(getorcreate_housenumber_id(make_standard_name(v))) from (select distinct housenumber as v from place where housenumber is not null) as w;
|
||||
|
||||
-- copy the word frequencies
|
||||
update word set search_name_count = count from word_frequencies wf where wf.word_token = word.word_token;
|
||||
|
||||
763
lib/Geocode.php
763
lib/Geocode.php
@@ -6,12 +6,15 @@
|
||||
protected $aLangPrefOrder = array();
|
||||
|
||||
protected $bIncludeAddressDetails = false;
|
||||
protected $bIncludeExtraTags = false;
|
||||
protected $bIncludeNameDetails = false;
|
||||
|
||||
protected $bIncludePolygonAsPoints = false;
|
||||
protected $bIncludePolygonAsText = false;
|
||||
protected $bIncludePolygonAsGeoJSON = false;
|
||||
protected $bIncludePolygonAsKML = false;
|
||||
protected $bIncludePolygonAsSVG = false;
|
||||
protected $fPolygonSimplificationThreshold = 0.0;
|
||||
|
||||
protected $aExcludePlaceIDs = array();
|
||||
protected $bDeDupe = true;
|
||||
@@ -67,6 +70,16 @@
|
||||
return $this->bIncludeAddressDetails;
|
||||
}
|
||||
|
||||
function getIncludeExtraTags()
|
||||
{
|
||||
return $this->bIncludeExtraTags;
|
||||
}
|
||||
|
||||
function getIncludeNameDetails()
|
||||
{
|
||||
return $this->bIncludeNameDetails;
|
||||
}
|
||||
|
||||
function setIncludePolygonAsPoints($b = true)
|
||||
{
|
||||
$this->bIncludePolygonAsPoints = $b;
|
||||
@@ -102,6 +115,11 @@
|
||||
$this->bIncludePolygonAsSVG = $b;
|
||||
}
|
||||
|
||||
function setPolygonSimplificationThreshold($f)
|
||||
{
|
||||
$this->fPolygonSimplificationThreshold = $f;
|
||||
}
|
||||
|
||||
function setDeDupe($bDeDupe = true)
|
||||
{
|
||||
$this->bDeDupe = (bool)$bDeDupe;
|
||||
@@ -208,6 +226,11 @@
|
||||
function loadParamArray($aParams)
|
||||
{
|
||||
if (isset($aParams['addressdetails'])) $this->bIncludeAddressDetails = (bool)$aParams['addressdetails'];
|
||||
if ((float) CONST_Postgresql_Version > 9.2)
|
||||
{
|
||||
if (isset($aParams['extratags'])) $this->bIncludeExtraTags = (bool)$aParams['extratags'];
|
||||
if (isset($aParams['namedetails'])) $this->bIncludeNameDetails = (bool)$aParams['namedetails'];
|
||||
}
|
||||
if (isset($aParams['bounded'])) $this->bBoundedSearch = (bool)$aParams['bounded'];
|
||||
if (isset($aParams['dedupe'])) $this->bDeDupe = (bool)$aParams['dedupe'];
|
||||
|
||||
@@ -222,9 +245,12 @@
|
||||
foreach(explode(',',$aParams['exclude_place_ids']) as $iExcludedPlaceID)
|
||||
{
|
||||
$iExcludedPlaceID = (int)$iExcludedPlaceID;
|
||||
if ($iExcludedPlaceID) $aExcludePlaceIDs[$iExcludedPlaceID] = $iExcludedPlaceID;
|
||||
if ($iExcludedPlaceID)
|
||||
$aExcludePlaceIDs[$iExcludedPlaceID] = $iExcludedPlaceID;
|
||||
}
|
||||
$this->aExcludePlaceIDs = $aExcludePlaceIDs;
|
||||
|
||||
if (isset($aExcludePlaceIDs))
|
||||
$this->aExcludePlaceIDs = $aExcludePlaceIDs;
|
||||
}
|
||||
|
||||
// Only certain ranks of feature
|
||||
@@ -380,6 +406,8 @@
|
||||
$sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= "get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
|
||||
$sSQL .= "get_name_by_language(name, ARRAY['ref']) as ref,";
|
||||
if ($this->bIncludeExtraTags) $sSQL .= "hstore_to_json(extratags)::text as extra,";
|
||||
if ($this->bIncludeNameDetails) $sSQL .= "hstore_to_json(name)::text as names,";
|
||||
$sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, ";
|
||||
$sSQL .= $sImportanceSQL."coalesce(importance,0.75-(rank_search::float/40)) as importance, ";
|
||||
$sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(CASE WHEN placex.rank_search < 28 THEN placex.place_id ELSE placex.parent_place_id END) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
|
||||
@@ -396,6 +424,8 @@
|
||||
$sSQL .= ",langaddress ";
|
||||
$sSQL .= ",placename ";
|
||||
$sSQL .= ",ref ";
|
||||
if ($this->bIncludeExtraTags) $sSQL .= ",extratags";
|
||||
if ($this->bIncludeNameDetails) $sSQL .= ",name";
|
||||
$sSQL .= ",extratags->'place' ";
|
||||
|
||||
if (30 >= $this->iMinAddressRank && 30 <= $this->iMaxAddressRank)
|
||||
@@ -405,6 +435,8 @@
|
||||
$sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= "null as placename,";
|
||||
$sSQL .= "null as ref,";
|
||||
if ($this->bIncludeExtraTags) $sSQL .= "null as extra,";
|
||||
if ($this->bIncludeNameDetails) $sSQL .= "null as names,";
|
||||
$sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, ";
|
||||
$sSQL .= $sImportanceSQL."-1.15 as importance, ";
|
||||
$sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_tiger.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
|
||||
@@ -418,6 +450,8 @@
|
||||
$sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= "null as placename,";
|
||||
$sSQL .= "null as ref,";
|
||||
if ($this->bIncludeExtraTags) $sSQL .= "null as extra,";
|
||||
if ($this->bIncludeNameDetails) $sSQL .= "null as names,";
|
||||
$sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, ";
|
||||
$sSQL .= $sImportanceSQL."-1.10 as importance, ";
|
||||
$sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_aux.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
|
||||
@@ -441,6 +475,283 @@
|
||||
return $aSearchResults;
|
||||
}
|
||||
|
||||
function getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases)
|
||||
{
|
||||
/*
|
||||
Calculate all searches using aValidTokens i.e.
|
||||
'Wodsworth Road, Sheffield' =>
|
||||
|
||||
Phrase Wordset
|
||||
0 0 (wodsworth road)
|
||||
0 1 (wodsworth)(road)
|
||||
1 0 (sheffield)
|
||||
|
||||
Score how good the search is so they can be ordered
|
||||
*/
|
||||
foreach($aPhrases as $iPhrase => $sPhrase)
|
||||
{
|
||||
$aNewPhraseSearches = array();
|
||||
if ($bStructuredPhrases) $sPhraseType = $aPhraseTypes[$iPhrase];
|
||||
else $sPhraseType = '';
|
||||
|
||||
foreach($aPhrases[$iPhrase]['wordsets'] as $iWordSet => $aWordset)
|
||||
{
|
||||
// Too many permutations - too expensive
|
||||
if ($iWordSet > 120) break;
|
||||
|
||||
$aWordsetSearches = $aSearches;
|
||||
|
||||
// Add all words from this wordset
|
||||
foreach($aWordset as $iToken => $sToken)
|
||||
{
|
||||
//echo "<br><b>$sToken</b>";
|
||||
$aNewWordsetSearches = array();
|
||||
|
||||
foreach($aWordsetSearches as $aCurrentSearch)
|
||||
{
|
||||
//echo "<i>";
|
||||
//var_dump($aCurrentSearch);
|
||||
//echo "</i>";
|
||||
|
||||
// If the token is valid
|
||||
if (isset($aValidTokens[' '.$sToken]))
|
||||
{
|
||||
foreach($aValidTokens[' '.$sToken] as $aSearchTerm)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank']++;
|
||||
if (($sPhraseType == '' || $sPhraseType == 'country') && !empty($aSearchTerm['country_code']) && $aSearchTerm['country_code'] != '0')
|
||||
{
|
||||
if ($aSearch['sCountryCode'] === false)
|
||||
{
|
||||
$aSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
|
||||
// Country is almost always at the end of the string - increase score for finding it anywhere else (optimisation)
|
||||
if (($iToken+1 != sizeof($aWordset) || $iPhrase+1 != sizeof($aPhrases)))
|
||||
{
|
||||
$aSearch['iSearchRank'] += 5;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif (isset($aSearchTerm['lat']) && $aSearchTerm['lat'] !== '' && $aSearchTerm['lat'] !== null)
|
||||
{
|
||||
if ($aSearch['fLat'] === '')
|
||||
{
|
||||
$aSearch['fLat'] = $aSearchTerm['lat'];
|
||||
$aSearch['fLon'] = $aSearchTerm['lon'];
|
||||
$aSearch['fRadius'] = $aSearchTerm['radius'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif ($sPhraseType == 'postalcode')
|
||||
{
|
||||
// We need to try the case where the postal code is the primary element (i.e. no way to tell if it is (postalcode, city) OR (city, postalcode) so try both
|
||||
if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
// If we already have a name try putting the postcode first
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
$aNewSearch = $aSearch;
|
||||
$aNewSearch['aAddress'] = array_merge($aNewSearch['aAddress'], $aNewSearch['aName']);
|
||||
$aNewSearch['aName'] = array();
|
||||
$aNewSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aNewSearch;
|
||||
}
|
||||
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1000; // skip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
//$aSearch['iNamePhrase'] = $iPhrase;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
|
||||
}
|
||||
elseif (($sPhraseType == '' || $sPhraseType == 'street') && $aSearchTerm['class'] == 'place' && $aSearchTerm['type'] == 'house')
|
||||
{
|
||||
if ($aSearch['sHouseNumber'] === '')
|
||||
{
|
||||
$aSearch['sHouseNumber'] = $sToken;
|
||||
// sanity check: if the housenumber is not mainly made
|
||||
// up of numbers, add a penalty
|
||||
if (preg_match_all("/[^0-9]/", $sToken, $aMatches) > 2) $aSearch['iSearchRank']++;
|
||||
// also housenumbers should appear in the first or second phrase
|
||||
if ($iPhrase > 1) $aSearch['iSearchRank'] += 1;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
/*
|
||||
// Fall back to not searching for this item (better than nothing)
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
*/
|
||||
}
|
||||
}
|
||||
elseif ($sPhraseType == '' && $aSearchTerm['class'] !== '' && $aSearchTerm['class'] !== null)
|
||||
{
|
||||
if ($aSearch['sClass'] === '')
|
||||
{
|
||||
$aSearch['sOperator'] = $aSearchTerm['operator'];
|
||||
$aSearch['sClass'] = $aSearchTerm['class'];
|
||||
$aSearch['sType'] = $aSearchTerm['type'];
|
||||
if (sizeof($aSearch['aName'])) $aSearch['sOperator'] = 'name';
|
||||
else $aSearch['sOperator'] = 'near'; // near = in for the moment
|
||||
if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
|
||||
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1000; // skip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
//$aSearch['iNamePhrase'] = $iPhrase;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look for partial matches.
|
||||
// Note that there is no point in adding country terms here
|
||||
// because country are omitted in the address.
|
||||
if (isset($aValidTokens[$sToken]) && $sPhraseType != 'country')
|
||||
{
|
||||
// Allow searching for a word - but at extra cost
|
||||
foreach($aValidTokens[$sToken] as $aSearchTerm)
|
||||
{
|
||||
if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strpos($sToken, ' ') === false)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
elseif (isset($aValidTokens[' '.$sToken])) // revert to the token version?
|
||||
{
|
||||
$aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
foreach($aValidTokens[' '.$sToken] as $aSearchTermToken)
|
||||
{
|
||||
if (empty($aSearchTermToken['country_code'])
|
||||
&& empty($aSearchTermToken['lat'])
|
||||
&& empty($aSearchTermToken['class']))
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
$aSearch['aAddress'][$aSearchTermToken['word_id']] = $aSearchTermToken['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeof($aCurrentSearch['aName']) || $aCurrentSearch['iNamePhrase'] == $iPhrase)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if (!sizeof($aCurrentSearch['aName'])) $aSearch['iSearchRank'] += 1;
|
||||
if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
|
||||
if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
else
|
||||
$aSearch['aNameNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iNamePhrase'] = $iPhrase;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow skipping a word - but at EXTREAM cost
|
||||
//$aSearch = $aCurrentSearch;
|
||||
//$aSearch['iSearchRank']+=100;
|
||||
//$aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
// Sort and cut
|
||||
usort($aNewWordsetSearches, 'bySearchRank');
|
||||
$aWordsetSearches = array_slice($aNewWordsetSearches, 0, 50);
|
||||
}
|
||||
//var_Dump('<hr>',sizeof($aWordsetSearches)); exit;
|
||||
|
||||
$aNewPhraseSearches = array_merge($aNewPhraseSearches, $aNewWordsetSearches);
|
||||
usort($aNewPhraseSearches, 'bySearchRank');
|
||||
|
||||
$aSearchHash = array();
|
||||
foreach($aNewPhraseSearches as $iSearch => $aSearch)
|
||||
{
|
||||
$sHash = serialize($aSearch);
|
||||
if (isset($aSearchHash[$sHash])) unset($aNewPhraseSearches[$iSearch]);
|
||||
else $aSearchHash[$sHash] = 1;
|
||||
}
|
||||
|
||||
$aNewPhraseSearches = array_slice($aNewPhraseSearches, 0, 50);
|
||||
}
|
||||
|
||||
// Re-group the searches by their score, junk anything over 20 as just not worth trying
|
||||
$aGroupedSearches = array();
|
||||
foreach($aNewPhraseSearches as $aSearch)
|
||||
{
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank)
|
||||
{
|
||||
if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
|
||||
$aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
|
||||
}
|
||||
}
|
||||
ksort($aGroupedSearches);
|
||||
|
||||
$iSearchCount = 0;
|
||||
$aSearches = array();
|
||||
foreach($aGroupedSearches as $iScore => $aNewSearches)
|
||||
{
|
||||
$iSearchCount += sizeof($aNewSearches);
|
||||
$aSearches = array_merge($aSearches, $aNewSearches);
|
||||
if ($iSearchCount > 50) break;
|
||||
}
|
||||
|
||||
//if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
|
||||
|
||||
}
|
||||
return $aGroupedSearches;
|
||||
|
||||
}
|
||||
|
||||
/* Perform the actual query lookup.
|
||||
|
||||
Returns an ordered list of results, each with the following fields:
|
||||
@@ -476,7 +787,6 @@
|
||||
if (!$this->sQuery && !$this->aStructuredQuery) return false;
|
||||
|
||||
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
|
||||
|
||||
$sCountryCodesSQL = false;
|
||||
if ($this->aCountryCodes && sizeof($this->aCountryCodes))
|
||||
{
|
||||
@@ -579,10 +889,10 @@
|
||||
|
||||
preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
|
||||
$aSpecialTerms = array();
|
||||
if (isset($aStructuredQuery['amenity']) && $aStructuredQuery['amenity'])
|
||||
if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity'])
|
||||
{
|
||||
$aSpecialTermsRaw[] = array('['.$aStructuredQuery['amenity'].']', $aStructuredQuery['amenity']);
|
||||
unset($aStructuredQuery['amenity']);
|
||||
$aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']);
|
||||
unset($this->aStructuredQuery['amenity']);
|
||||
}
|
||||
foreach($aSpecialTermsRaw as $aSpecialTerm)
|
||||
{
|
||||
@@ -680,8 +990,8 @@
|
||||
foreach($aDatabaseWords as $aToken)
|
||||
{
|
||||
// Very special case - require 2 letter country param to match the country code found
|
||||
if ($bStructuredPhrases && $aToken['country_code'] && !empty($aStructuredQuery['country'])
|
||||
&& strlen($aStructuredQuery['country']) == 2 && strtolower($aStructuredQuery['country']) != $aToken['country_code'])
|
||||
if ($bStructuredPhrases && $aToken['country_code'] && !empty($this->aStructuredQuery['country'])
|
||||
&& strlen($this->aStructuredQuery['country']) == 2 && strtolower($this->aStructuredQuery['country']) != $aToken['country_code'])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -755,287 +1065,38 @@
|
||||
// Start the search process
|
||||
$aResultPlaceIDs = array();
|
||||
|
||||
/*
|
||||
Calculate all searches using aValidTokens i.e.
|
||||
'Wodsworth Road, Sheffield' =>
|
||||
$aGroupedSearches = $this->getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases);
|
||||
|
||||
Phrase Wordset
|
||||
0 0 (wodsworth road)
|
||||
0 1 (wodsworth)(road)
|
||||
1 0 (sheffield)
|
||||
|
||||
Score how good the search is so they can be ordered
|
||||
*/
|
||||
foreach($aPhrases as $iPhrase => $sPhrase)
|
||||
if ($this->bReverseInPlan)
|
||||
{
|
||||
$aNewPhraseSearches = array();
|
||||
if ($bStructuredPhrases) $sPhraseType = $aPhraseTypes[$iPhrase];
|
||||
else $sPhraseType = '';
|
||||
|
||||
foreach($aPhrases[$iPhrase]['wordsets'] as $iWordSet => $aWordset)
|
||||
// Reverse phrase array and also reverse the order of the wordsets in
|
||||
// the first and final phrase. Don't bother about phrases in the middle
|
||||
// because order in the address doesn't matter.
|
||||
$aPhrases = array_reverse($aPhrases);
|
||||
$aPhrases[0]['wordsets'] = getInverseWordSets($aPhrases[0]['words'], 0);
|
||||
if (sizeof($aPhrases) > 1)
|
||||
{
|
||||
// Too many permutations - too expensive
|
||||
if ($iWordSet > 120) break;
|
||||
$aFinalPhrase = end($aPhrases);
|
||||
$aPhrases[sizeof($aPhrases)-1]['wordsets'] = getInverseWordSets($aFinalPhrase['words'], 0);
|
||||
}
|
||||
$aReverseGroupedSearches = $this->getGroupedSearches($aSearches, null, $aPhrases, $aValidTokens, $aWordFrequencyScores, false);
|
||||
|
||||
$aWordsetSearches = $aSearches;
|
||||
|
||||
// Add all words from this wordset
|
||||
foreach($aWordset as $iToken => $sToken)
|
||||
foreach($aGroupedSearches as $aSearches)
|
||||
{
|
||||
foreach($aSearches as $aSearch)
|
||||
{
|
||||
//echo "<br><b>$sToken</b>";
|
||||
$aNewWordsetSearches = array();
|
||||
|
||||
foreach($aWordsetSearches as $aCurrentSearch)
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank)
|
||||
{
|
||||
//echo "<i>";
|
||||
//var_dump($aCurrentSearch);
|
||||
//echo "</i>";
|
||||
|
||||
// If the token is valid
|
||||
if (isset($aValidTokens[' '.$sToken]))
|
||||
{
|
||||
foreach($aValidTokens[' '.$sToken] as $aSearchTerm)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank']++;
|
||||
if (($sPhraseType == '' || $sPhraseType == 'country') && !empty($aSearchTerm['country_code']) && $aSearchTerm['country_code'] != '0')
|
||||
{
|
||||
if ($aSearch['sCountryCode'] === false)
|
||||
{
|
||||
$aSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
|
||||
// Country is almost always at the end of the string - increase score for finding it anywhere else (optimisation)
|
||||
// If reverse order is enabled, it may appear at the beginning as well.
|
||||
if (($iToken+1 != sizeof($aWordset) || $iPhrase+1 != sizeof($aPhrases)) &&
|
||||
(!$this->bReverseInPlan || $iToken > 0 || $iPhrase > 0))
|
||||
{
|
||||
$aSearch['iSearchRank'] += 5;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif (isset($aSearchTerm['lat']) && $aSearchTerm['lat'] !== '' && $aSearchTerm['lat'] !== null)
|
||||
{
|
||||
if ($aSearch['fLat'] === '')
|
||||
{
|
||||
$aSearch['fLat'] = $aSearchTerm['lat'];
|
||||
$aSearch['fLon'] = $aSearchTerm['lon'];
|
||||
$aSearch['fRadius'] = $aSearchTerm['radius'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif ($sPhraseType == 'postalcode')
|
||||
{
|
||||
// We need to try the case where the postal code is the primary element (i.e. no way to tell if it is (postalcode, city) OR (city, postalcode) so try both
|
||||
if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
// If we already have a name try putting the postcode first
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
$aNewSearch = $aSearch;
|
||||
$aNewSearch['aAddress'] = array_merge($aNewSearch['aAddress'], $aNewSearch['aName']);
|
||||
$aNewSearch['aName'] = array();
|
||||
$aNewSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aNewSearch;
|
||||
}
|
||||
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strlen($sToken) < 4 || strpos($sToken, ' ') !== false))
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1000; // skip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
//$aSearch['iNamePhrase'] = $iPhrase;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
|
||||
}
|
||||
elseif (($sPhraseType == '' || $sPhraseType == 'street') && $aSearchTerm['class'] == 'place' && $aSearchTerm['type'] == 'house')
|
||||
{
|
||||
if ($aSearch['sHouseNumber'] === '')
|
||||
{
|
||||
$aSearch['sHouseNumber'] = $sToken;
|
||||
// sanity check: if the housenumber is not mainly made
|
||||
// up of numbers, add a penalty
|
||||
if (preg_match_all("/[^0-9]/", $sToken, $aMatches) > 2) $aSearch['iSearchRank']++;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
/*
|
||||
// Fall back to not searching for this item (better than nothing)
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
*/
|
||||
}
|
||||
}
|
||||
elseif ($sPhraseType == '' && $aSearchTerm['class'] !== '' && $aSearchTerm['class'] !== null)
|
||||
{
|
||||
if ($aSearch['sClass'] === '')
|
||||
{
|
||||
$aSearch['sOperator'] = $aSearchTerm['operator'];
|
||||
$aSearch['sClass'] = $aSearchTerm['class'];
|
||||
$aSearch['sType'] = $aSearchTerm['type'];
|
||||
if (sizeof($aSearch['aName'])) $aSearch['sOperator'] = 'name';
|
||||
else $aSearch['sOperator'] = 'near'; // near = in for the moment
|
||||
if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
|
||||
|
||||
// Do we have a shortcut id?
|
||||
if ($aSearch['sOperator'] == 'name')
|
||||
{
|
||||
$sSQL = "select get_tagpair('".$aSearch['sClass']."', '".$aSearch['sType']."')";
|
||||
if ($iAmenityID = $this->oDB->getOne($sSQL))
|
||||
{
|
||||
$aValidTokens[$aSearch['sClass'].':'.$aSearch['sType']] = array('word_id' => $iAmenityID);
|
||||
$aSearch['aName'][$iAmenityID] = $iAmenityID;
|
||||
$aSearch['sClass'] = '';
|
||||
$aSearch['sType'] = '';
|
||||
}
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
elseif (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
if (sizeof($aSearch['aName']))
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strlen($sToken) < 4 || strpos($sToken, ' ') !== false))
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1000; // skip;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
//$aSearch['iNamePhrase'] = $iPhrase;
|
||||
}
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($aValidTokens[$sToken]))
|
||||
{
|
||||
// Allow searching for a word - but at extra cost
|
||||
foreach($aValidTokens[$sToken] as $aSearchTerm)
|
||||
{
|
||||
if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
|
||||
{
|
||||
if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strpos($sToken, ' ') === false)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
|
||||
{
|
||||
$aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
elseif (isset($aValidTokens[' '.$sToken]) && strlen($sToken) >= 4) // revert to the token version?
|
||||
{
|
||||
$aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
foreach($aValidTokens[' '.$sToken] as $aSearchTermToken)
|
||||
{
|
||||
if (empty($aSearchTermToken['country_code'])
|
||||
&& empty($aSearchTermToken['lat'])
|
||||
&& empty($aSearchTermToken['class']))
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
$aSearch['aAddress'][$aSearchTermToken['word_id']] = $aSearchTermToken['word_id'];
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sizeof($aCurrentSearch['aName']) || $aCurrentSearch['iNamePhrase'] == $iPhrase)
|
||||
{
|
||||
$aSearch = $aCurrentSearch;
|
||||
$aSearch['iSearchRank'] += 1;
|
||||
if (!sizeof($aCurrentSearch['aName'])) $aSearch['iSearchRank'] += 1;
|
||||
if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
|
||||
if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
|
||||
$aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
else
|
||||
$aSearch['aNameNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
|
||||
$aSearch['iNamePhrase'] = $iPhrase;
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow skipping a word - but at EXTREAM cost
|
||||
//$aSearch = $aCurrentSearch;
|
||||
//$aSearch['iSearchRank']+=100;
|
||||
//$aNewWordsetSearches[] = $aSearch;
|
||||
}
|
||||
if (!isset($aReverseGroupedSearches[$aSearch['iSearchRank']])) $aReverseGroupedSearches[$aSearch['iSearchRank']] = array();
|
||||
$aReverseGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
|
||||
}
|
||||
// Sort and cut
|
||||
usort($aNewWordsetSearches, 'bySearchRank');
|
||||
$aWordsetSearches = array_slice($aNewWordsetSearches, 0, 50);
|
||||
}
|
||||
//var_Dump('<hr>',sizeof($aWordsetSearches)); exit;
|
||||
|
||||
$aNewPhraseSearches = array_merge($aNewPhraseSearches, $aNewWordsetSearches);
|
||||
usort($aNewPhraseSearches, 'bySearchRank');
|
||||
|
||||
$aSearchHash = array();
|
||||
foreach($aNewPhraseSearches as $iSearch => $aSearch)
|
||||
{
|
||||
$sHash = serialize($aSearch);
|
||||
if (isset($aSearchHash[$sHash])) unset($aNewPhraseSearches[$iSearch]);
|
||||
else $aSearchHash[$sHash] = 1;
|
||||
}
|
||||
|
||||
$aNewPhraseSearches = array_slice($aNewPhraseSearches, 0, 50);
|
||||
}
|
||||
|
||||
// Re-group the searches by their score, junk anything over 20 as just not worth trying
|
||||
$aGroupedSearches = array();
|
||||
foreach($aNewPhraseSearches as $aSearch)
|
||||
{
|
||||
if ($aSearch['iSearchRank'] < $this->iMaxRank)
|
||||
{
|
||||
if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
|
||||
$aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
|
||||
}
|
||||
}
|
||||
|
||||
$aGroupedSearches = $aReverseGroupedSearches;
|
||||
ksort($aGroupedSearches);
|
||||
|
||||
$iSearchCount = 0;
|
||||
$aSearches = array();
|
||||
foreach($aGroupedSearches as $iScore => $aNewSearches)
|
||||
{
|
||||
$iSearchCount += sizeof($aNewSearches);
|
||||
$aSearches = array_merge($aSearches, $aNewSearches);
|
||||
if ($iSearchCount > 50) break;
|
||||
}
|
||||
|
||||
//if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1054,30 +1115,7 @@
|
||||
|
||||
if (CONST_Debug) var_Dump($aGroupedSearches);
|
||||
|
||||
if ($this->bReverseInPlan)
|
||||
{
|
||||
$aCopyGroupedSearches = $aGroupedSearches;
|
||||
foreach($aCopyGroupedSearches as $iGroup => $aSearches)
|
||||
{
|
||||
foreach($aSearches as $iSearch => $aSearch)
|
||||
{
|
||||
if (sizeof($aSearch['aAddress']))
|
||||
{
|
||||
$iReverseItem = array_pop($aSearch['aAddress']);
|
||||
if (isset($aPossibleMainWordIDs[$iReverseItem]))
|
||||
{
|
||||
$aSearch['aAddress'] = array_merge($aSearch['aAddress'], $aSearch['aName']);
|
||||
$aSearch['aName'] = array($iReverseItem);
|
||||
$aGroupedSearches[$iGroup][] = $aSearch;
|
||||
}
|
||||
//$aReverseSearch['aName'][$iReverseItem] = $iReverseItem;
|
||||
//$aGroupedSearches[$iGroup][] = $aReverseSearch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CONST_Search_TryDroppedAddressTerms && sizeof($aStructuredQuery) > 0)
|
||||
if (CONST_Search_TryDroppedAddressTerms && sizeof($this->aStructuredQuery) > 0)
|
||||
{
|
||||
$aCopyGroupedSearches = $aGroupedSearches;
|
||||
foreach($aCopyGroupedSearches as $iGroup => $aSearches)
|
||||
@@ -1156,6 +1194,8 @@
|
||||
{
|
||||
$sSQL = "select place_id from placex where calculated_country_code='".$aSearch['sCountryCode']."' and rank_search = 4";
|
||||
if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
|
||||
if ($bBoundingBoxSearch)
|
||||
$sSQL .= " and _st_intersects($this->sViewboxSmallSQL, geometry)";
|
||||
$sSQL .= " order by st_area(geometry) desc limit 1";
|
||||
if (CONST_Debug) var_dump($sSQL);
|
||||
$aPlaceIDs = $this->oDB->getCol($sSQL);
|
||||
@@ -1221,6 +1261,12 @@
|
||||
$aTerms = array();
|
||||
$aOrder = array();
|
||||
|
||||
if ($aSearch['sHouseNumber'] && sizeof($aSearch['aAddress']))
|
||||
{
|
||||
$sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
|
||||
$aOrder[] = "exists(select place_id from placex where parent_place_id = search_name.place_id and transliteration(housenumber) ~* E'".$sHouseNumberRegex."' limit 1) desc";
|
||||
}
|
||||
|
||||
// TODO: filter out the pointless search terms (2 letter name tokens and less)
|
||||
// they might be right - but they are just too darned expensive to run
|
||||
if (sizeof($aSearch['aName'])) $aTerms[] = "name_vector @> ARRAY[".join($aSearch['aName'],",")."]";
|
||||
@@ -1301,7 +1347,7 @@
|
||||
$sSQL .= " where ".join(' and ',$aTerms);
|
||||
$sSQL .= " order by ".join(', ',$aOrder);
|
||||
if ($aSearch['sHouseNumber'] || $aSearch['sClass'])
|
||||
$sSQL .= " limit 50";
|
||||
$sSQL .= " limit 20";
|
||||
elseif (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && $aSearch['sClass'])
|
||||
$sSQL .= " limit 1";
|
||||
else
|
||||
@@ -1566,23 +1612,49 @@
|
||||
$aRecheckWords = preg_split('/\b[\s,\\-]*/u',$sQuery);
|
||||
foreach($aRecheckWords as $i => $sWord)
|
||||
{
|
||||
if (!$sWord) unset($aRecheckWords[$i]);
|
||||
if (!preg_match('/\pL/', $sWord)) unset($aRecheckWords[$i]);
|
||||
}
|
||||
|
||||
if (CONST_Debug) { echo '<i>Recheck words:<\i>'; var_dump($aRecheckWords); }
|
||||
|
||||
foreach($aSearchResults as $iResNum => $aResult)
|
||||
{
|
||||
// Default
|
||||
$fDiameter = 0.0001;
|
||||
|
||||
if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
|
||||
&& $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
|
||||
{
|
||||
$fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'];
|
||||
}
|
||||
elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
|
||||
&& $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
|
||||
{
|
||||
$fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
|
||||
}
|
||||
$fRadius = $fDiameter / 2;
|
||||
|
||||
if (CONST_Search_AreaPolygons)
|
||||
{
|
||||
// Get the bounding box and outline polygon
|
||||
$sSQL = "select place_id,0 as numfeatures,st_area(geometry) as area,";
|
||||
$sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
|
||||
$sSQL .= "ST_Y(ST_PointN(ST_ExteriorRing(Box2D(geometry)),4)) as minlat,ST_Y(ST_PointN(ST_ExteriorRing(Box2D(geometry)),2)) as maxlat,";
|
||||
$sSQL .= "ST_X(ST_PointN(ST_ExteriorRing(Box2D(geometry)),1)) as minlon,ST_X(ST_PointN(ST_ExteriorRing(Box2D(geometry)),3)) as maxlon";
|
||||
$sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
|
||||
$sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
|
||||
if ($this->bIncludePolygonAsGeoJSON) $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson";
|
||||
if ($this->bIncludePolygonAsKML) $sSQL .= ",ST_AsKML(geometry) as askml";
|
||||
if ($this->bIncludePolygonAsSVG) $sSQL .= ",ST_AsSVG(geometry) as assvg";
|
||||
if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) $sSQL .= ",ST_AsText(geometry) as astext";
|
||||
$sSQL .= " from placex where place_id = ".$aResult['place_id'].' and st_geometrytype(Box2D(geometry)) = \'ST_Polygon\'';
|
||||
$sFrom = " from placex where place_id = ".$aResult['place_id'];
|
||||
if ($this->fPolygonSimplificationThreshold > 0)
|
||||
{
|
||||
$sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQL .= $sFrom;
|
||||
}
|
||||
|
||||
$aPointPolygon = $this->oDB->getRow($sSQL);
|
||||
if (PEAR::IsError($aPointPolygon))
|
||||
{
|
||||
@@ -1604,7 +1676,7 @@
|
||||
|
||||
if ($this->bIncludePolygonAsPoints)
|
||||
{
|
||||
// Translate geometary string to point array
|
||||
// Translate geometry string to point array
|
||||
if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch))
|
||||
{
|
||||
preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
|
||||
@@ -1615,18 +1687,13 @@
|
||||
}
|
||||
elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['astext'],$aMatch))
|
||||
{
|
||||
$fRadius = 0.01;
|
||||
$iSteps = ($fRadius * 40000)^2;
|
||||
$iSteps = max(8, min(100, ($fRadius * 40000)^2));
|
||||
$fStepSize = (2*pi())/$iSteps;
|
||||
$aPolyPoints = array();
|
||||
for($f = 0; $f < 2*pi(); $f += $fStepSize)
|
||||
{
|
||||
$aPolyPoints[] = array('',$aMatch[1]+($fRadius*sin($f)),$aMatch[2]+($fRadius*cos($f)));
|
||||
}
|
||||
$aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
|
||||
$aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
|
||||
$aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
|
||||
$aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1639,7 +1706,18 @@
|
||||
$aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
|
||||
}
|
||||
}
|
||||
$aResult['aBoundingBox'] = array($aPointPolygon['minlat'],$aPointPolygon['maxlat'],$aPointPolygon['minlon'],$aPointPolygon['maxlon']);
|
||||
|
||||
if (abs($aPointPolygon['minlat'] - $aPointPolygon['maxlat']) < 0.0000001)
|
||||
{
|
||||
$aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
|
||||
$aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
|
||||
}
|
||||
if (abs($aPointPolygon['minlon'] - $aPointPolygon['maxlon']) < 0.0000001)
|
||||
{
|
||||
$aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
|
||||
$aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
|
||||
}
|
||||
$aResult['aBoundingBox'] = array((string)$aPointPolygon['minlat'],(string)$aPointPolygon['maxlat'],(string)$aPointPolygon['minlon'],(string)$aPointPolygon['maxlon']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1652,28 +1730,8 @@
|
||||
|
||||
if (!isset($aResult['aBoundingBox']))
|
||||
{
|
||||
// Default
|
||||
$fDiameter = 0.0001;
|
||||
|
||||
if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
|
||||
&& $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
|
||||
{
|
||||
$fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defzoom'];
|
||||
}
|
||||
elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
|
||||
&& $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
|
||||
{
|
||||
$fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
|
||||
}
|
||||
$fRadius = $fDiameter / 2;
|
||||
|
||||
$iSteps = max(8,min(100,$fRadius * 3.14 * 100000));
|
||||
$fStepSize = (2*pi())/$iSteps;
|
||||
$aPolyPoints = array();
|
||||
for($f = 0; $f < 2*pi(); $f += $fStepSize)
|
||||
{
|
||||
$aPolyPoints[] = array('',$aResult['lon']+($fRadius*sin($f)),$aResult['lat']+($fRadius*cos($f)));
|
||||
}
|
||||
$aPointPolygon['minlat'] = $aResult['lat'] - $fRadius;
|
||||
$aPointPolygon['maxlat'] = $aResult['lat'] + $fRadius;
|
||||
$aPointPolygon['minlon'] = $aResult['lon'] - $fRadius;
|
||||
@@ -1682,6 +1740,11 @@
|
||||
// Output data suitable for display (points and a bounding box)
|
||||
if ($this->bIncludePolygonAsPoints)
|
||||
{
|
||||
$aPolyPoints = array();
|
||||
for($f = 0; $f < 2*pi(); $f += $fStepSize)
|
||||
{
|
||||
$aPolyPoints[] = array('',$aResult['lon']+($fRadius*sin($f)),$aResult['lat']+($fRadius*cos($f)));
|
||||
}
|
||||
$aResult['aPolyPoints'] = array();
|
||||
foreach($aPolyPoints as $aPoint)
|
||||
{
|
||||
@@ -1718,6 +1781,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->bIncludeExtraTags)
|
||||
{
|
||||
if ($aResult['extra'])
|
||||
{
|
||||
$aResult['sExtraTags'] = json_decode($aResult['extra']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult['sExtraTags'] = (object) array();
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->bIncludeNameDetails)
|
||||
{
|
||||
if ($aResult['names'])
|
||||
{
|
||||
$aResult['sNameDetails'] = json_decode($aResult['names']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult['sNameDetails'] = (object) array();
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust importance for the number of exact string matches in the result
|
||||
$aResult['importance'] = max(0.001,$aResult['importance']);
|
||||
$iCountWords = 0;
|
||||
@@ -1727,7 +1814,7 @@
|
||||
if (stripos($sAddress, $sWord)!==false)
|
||||
{
|
||||
$iCountWords++;
|
||||
if (preg_match("/(^|,)\s*$sWord\s*(,|$)/", $sAddress)) $iCountWords += 0.1;
|
||||
if (preg_match("/(^|,)\s*".preg_quote($sWord, '/')."\s*(,|$)/", $sAddress)) $iCountWords += 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1746,12 +1833,13 @@
|
||||
if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
|
||||
&& $aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
|
||||
{
|
||||
$aResult['foundorder'] = $aResult['foundorder'] + 0.000001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
|
||||
$aResult['foundorder'] += 0.0001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aResult['foundorder'] = $aResult['foundorder'] + 0.001;
|
||||
$aResult['foundorder'] += 0.01;
|
||||
}
|
||||
if (CONST_Debug) { var_dump($aResult); }
|
||||
$aSearchResults[$iResNum] = $aResult;
|
||||
}
|
||||
uasort($aSearchResults, 'byImportance');
|
||||
@@ -1764,7 +1852,6 @@
|
||||
$bFirst = true;
|
||||
foreach($aToFilter as $iResNum => $aResult)
|
||||
{
|
||||
if ($aResult['type'] == 'adminitrative') $aResult['type'] = 'administrative';
|
||||
$this->aExcludePlaceIDs[$aResult['place_id']] = $aResult['place_id'];
|
||||
if ($bFirst)
|
||||
{
|
||||
|
||||
@@ -5,10 +5,16 @@
|
||||
|
||||
protected $iPlaceID;
|
||||
|
||||
protected $sType = false;
|
||||
|
||||
protected $aLangPrefOrder = array();
|
||||
|
||||
protected $bAddressDetails = false;
|
||||
|
||||
protected $bExtraTags = false;
|
||||
|
||||
protected $bNameDetails = false;
|
||||
|
||||
function PlaceLookup(&$oDB)
|
||||
{
|
||||
$this->oDB =& $oDB;
|
||||
@@ -24,6 +30,22 @@
|
||||
$this->bAddressDetails = $bAddressDetails;
|
||||
}
|
||||
|
||||
function setIncludeExtraTags($bExtraTags = false)
|
||||
{
|
||||
if ((float) CONST_Postgresql_Version > 9.2)
|
||||
{
|
||||
$this->bExtraTags = $bExtraTags;
|
||||
}
|
||||
}
|
||||
|
||||
function setIncludeNameDetails($bNameDetails = false)
|
||||
{
|
||||
if ((float) CONST_Postgresql_Version > 9.2)
|
||||
{
|
||||
$this->bNameDetails = $bNameDetails;
|
||||
}
|
||||
}
|
||||
|
||||
function setPlaceID($iPlaceID)
|
||||
{
|
||||
$this->iPlaceID = $iPlaceID;
|
||||
@@ -35,21 +57,60 @@
|
||||
$this->iPlaceID = $this->oDB->getOne($sSQL);
|
||||
}
|
||||
|
||||
function lookupPlace($details)
|
||||
{
|
||||
if (isset($details['place_id'])) $this->iPlaceID = $details['place_id'];
|
||||
if (isset($details['type'])) $this->sType = $details['type'];
|
||||
if (isset($details['osm_type']) && isset($details['osm_id']))
|
||||
{
|
||||
$this->setOSMID($details['osm_type'], $details['osm_id']);
|
||||
}
|
||||
|
||||
return $this->lookup();
|
||||
}
|
||||
|
||||
function lookup()
|
||||
{
|
||||
if (!$this->iPlaceID) return null;
|
||||
|
||||
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted", $this->aLangPrefOrder))."]";
|
||||
|
||||
$sSQL = "select placex.place_id, partition, osm_type, osm_id, class, type, admin_level, housenumber, street, isin, postcode, country_code, extratags, parent_place_id, linked_place_id, rank_address, rank_search, ";
|
||||
$sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, calculated_country_code, ";
|
||||
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
|
||||
$sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,";
|
||||
$sSQL .= " st_y(centroid) as lat, st_x(centroid) as lon";
|
||||
$sSQL .= " from placex where place_id = ".(int)$this->iPlaceID;
|
||||
if ($this->sType == 'tiger')
|
||||
{
|
||||
$sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, null as street, null as isin, postcode,";
|
||||
$sSQL .= " 'us' as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
|
||||
$sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, ";
|
||||
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= " null as placename,";
|
||||
$sSQL .= " null as ref,";
|
||||
if ($this->bExtraTags) $sSQL .= " null as extra,";
|
||||
if ($this->bNameDetails) $sSQL .= " null as names,";
|
||||
$sSQL .= " st_y(centroid) as lat,";
|
||||
$sSQL .= " st_x(centroid) as lon";
|
||||
$sSQL .= " from location_property_tiger where place_id = ".(int)$this->iPlaceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sSQL = "select placex.place_id, partition, osm_type, osm_id, class, type, admin_level, housenumber, street, isin, postcode, country_code, parent_place_id, linked_place_id, rank_address, rank_search, ";
|
||||
$sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, calculated_country_code, ";
|
||||
$sSQL .= " get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
|
||||
$sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
|
||||
$sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,";
|
||||
if ($this->bExtraTags) $sSQL .= " hstore_to_json(extratags) as extra,";
|
||||
if ($this->bNameDetails) $sSQL .= " hstore_to_json(name) as names,";
|
||||
$sSQL .= " (case when centroid is null then st_y(st_centroid(geometry)) else st_y(centroid) end) as lat,";
|
||||
$sSQL .= " (case when centroid is null then st_x(st_centroid(geometry)) else st_x(centroid) end) as lon";
|
||||
$sSQL .= " from placex where place_id = ".(int)$this->iPlaceID;
|
||||
}
|
||||
|
||||
$aPlace = $this->oDB->getRow($sSQL);
|
||||
|
||||
|
||||
if (PEAR::IsError($aPlace))
|
||||
{
|
||||
failInternalError("Could not lookup place.", $sSQL, $aPlace);
|
||||
}
|
||||
|
||||
if (!$aPlace['place_id']) return null;
|
||||
|
||||
if ($this->bAddressDetails)
|
||||
@@ -58,6 +119,30 @@
|
||||
$aPlace['aAddress'] = $aAddress;
|
||||
}
|
||||
|
||||
if ($this->bExtraTags)
|
||||
{
|
||||
if ($aPlace['extra'])
|
||||
{
|
||||
$aPlace['sExtraTags'] = json_decode($aPlace['extra']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPlace['sExtraTags'] = (object) array();
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->bNameDetails)
|
||||
{
|
||||
if ($aPlace['names'])
|
||||
{
|
||||
$aPlace['sNameDetails'] = json_decode($aPlace['names']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPlace['sNameDetails'] = (object) array();
|
||||
}
|
||||
}
|
||||
|
||||
$aClassType = getClassTypes();
|
||||
$sAddressType = '';
|
||||
$sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
|
||||
@@ -99,7 +184,7 @@
|
||||
|
||||
function getAddressNames()
|
||||
{
|
||||
$aAddressLines = $this->getAddressDetails(false);;
|
||||
$aAddressLines = $this->getAddressDetails(false);
|
||||
|
||||
$aAddress = array();
|
||||
$aFallback = array();
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
protected $aLangPrefOrder = array();
|
||||
|
||||
protected $bShowAddressDetails = true;
|
||||
|
||||
function ReverseGeocode(&$oDB)
|
||||
{
|
||||
$this->oDB =& $oDB;
|
||||
@@ -21,11 +19,6 @@
|
||||
$this->aLangPrefOrder = $aLangPref;
|
||||
}
|
||||
|
||||
function setIncludeAddressDetails($bAddressDetails = true)
|
||||
{
|
||||
$this->bAddressDetails = $bAddressDetails;
|
||||
}
|
||||
|
||||
function setLatLon($fLat, $fLon)
|
||||
{
|
||||
$this->fLat = (float)$fLat;
|
||||
@@ -69,12 +62,15 @@
|
||||
{
|
||||
$sPointSQL = 'ST_SetSRID(ST_Point('.$this->fLon.','.$this->fLat.'),4326)';
|
||||
$iMaxRank = $this->iMaxRank;
|
||||
$iMaxRank_orig = $this->iMaxRank;
|
||||
|
||||
// Find the nearest point
|
||||
$fSearchDiam = 0.0004;
|
||||
$iPlaceID = null;
|
||||
$aArea = false;
|
||||
$fMaxAreaDistance = 1;
|
||||
$bIsInUnitedStates = false;
|
||||
$bPlaceIsTiger = false;
|
||||
while(!$iPlaceID && $fSearchDiam < $fMaxAreaDistance)
|
||||
{
|
||||
$fSearchDiam = $fSearchDiam * 2;
|
||||
@@ -90,11 +86,11 @@
|
||||
if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
|
||||
if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
|
||||
|
||||
$sSQL = 'select place_id,parent_place_id,rank_search from placex';
|
||||
$sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code from placex';
|
||||
$sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
|
||||
$sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank;
|
||||
$sSQL .= ' and (name is not null or housenumber is not null)';
|
||||
$sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\')';
|
||||
$sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\',\'man_made\')';
|
||||
$sSQL .= ' and indexed_status = 0 ';
|
||||
$sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ';
|
||||
$sSQL .= ' OR ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.'))';
|
||||
@@ -107,12 +103,52 @@
|
||||
}
|
||||
$iPlaceID = $aPlace['place_id'];
|
||||
$iParentPlaceID = $aPlace['parent_place_id'];
|
||||
$bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us');
|
||||
}
|
||||
|
||||
// Only street found? If it's in the US we can check TIGER data for nearest housenumber
|
||||
if ($bIsInUnitedStates && $iMaxRank_orig >= 28 && $iPlaceID && ($aPlace['rank_search'] == 26 || $aPlace['rank_search'] == 27 ))
|
||||
{
|
||||
$fSearchDiam = 0.001;
|
||||
$sSQL = 'SELECT place_id,parent_place_id,30 as rank_search ';
|
||||
if (CONST_Debug) { $sSQL .= ', housenumber, ST_distance('.$sPointSQL.', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon'; }
|
||||
$sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$iPlaceID;
|
||||
$sSQL .= ' AND ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.')';
|
||||
$sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', centroid) ASC limit 1';
|
||||
|
||||
|
||||
// print all house numbers in the parent (street)
|
||||
if (CONST_Debug)
|
||||
{
|
||||
$sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
|
||||
var_dump($sSQL);
|
||||
|
||||
$aAllHouses = $this->oDB->getAll($sSQL);
|
||||
foreach($aAllHouses as $i)
|
||||
{
|
||||
echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$aPlaceTiger = $this->oDB->getRow($sSQL);
|
||||
if (PEAR::IsError($aPlace))
|
||||
{
|
||||
failInternalError("Could not determine closest Tiger place.", $sSQL, $aPlaceTiger);
|
||||
}
|
||||
if ($aPlaceTiger)
|
||||
{
|
||||
if (CONST_Debug) var_dump('found Tiger place', $aPlaceTiger);
|
||||
$bPlaceIsTiger = true;
|
||||
$aPlace = $aPlaceTiger;
|
||||
$iPlaceID = $aPlaceTiger['place_id'];
|
||||
$iParentPlaceID = $aPlaceTiger['parent_place_id']; // the street
|
||||
}
|
||||
}
|
||||
|
||||
// The point we found might be too small - use the address to find what it is a child of
|
||||
if ($iPlaceID && $iMaxRank < 28)
|
||||
{
|
||||
if ($aPlace['rank_search'] > 28 && $iParentPlaceID)
|
||||
if ($aPlace['rank_search'] > 28 && $iParentPlaceID && !$bPlaceIsTiger)
|
||||
{
|
||||
$iPlaceID = $iParentPlaceID;
|
||||
}
|
||||
@@ -128,12 +164,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
$oPlaceLookup = new PlaceLookup($this->oDB);
|
||||
$oPlaceLookup->setLanguagePreference($this->aLangPrefOrder);
|
||||
$oPlaceLookup->setIncludeAddressDetails($this->bAddressDetails);
|
||||
$oPlaceLookup->setPlaceId($iPlaceID);
|
||||
|
||||
return $oPlaceLookup->lookup();
|
||||
return array('place_id' => $iPlaceID,
|
||||
'type' => $bPlaceIsTiger ? 'tiger' : 'osm');
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
function &getDB($bNew = false, $bPersistent = false)
|
||||
{
|
||||
// Get the database object
|
||||
$oDB =& DB::connect(CONST_Database_DSN.($bNew?'?new_link=true':''), $bPersistent);
|
||||
$oDB = DB::connect(CONST_Database_DSN.($bNew?'?new_link=true':''), $bPersistent);
|
||||
if (PEAR::IsError($oDB))
|
||||
{
|
||||
var_dump(CONST_Database_DSN);
|
||||
@@ -14,6 +14,8 @@
|
||||
$oDB->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||
$oDB->query("SET DateStyle TO 'sql,european'");
|
||||
$oDB->query("SET client_encoding TO 'utf-8'");
|
||||
$iMaxExecution = ini_get('max_execution_time') * 1000;
|
||||
if ($iMaxExecution > 0) $oDB->query("SET statement_timeout TO $iMaxExecution");
|
||||
return $oDB;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,3 +6,26 @@
|
||||
|
||||
require_once('init.php');
|
||||
require_once('cmd.php');
|
||||
|
||||
// handle http proxy when using file_get_contents
|
||||
if (CONST_HTTP_Proxy) {
|
||||
$proxy = 'tcp://' . CONST_HTTP_Proxy_Host . ':' . CONST_HTTP_Proxy_Port;
|
||||
$aHeaders = array();
|
||||
if(CONST_HTTP_Proxy_Login != null && CONST_HTTP_Proxy_Login != '' && CONST_HTTP_Proxy_Password != null && CONST_HTTP_Proxy_Password != '') {
|
||||
$auth = base64_encode(CONST_HTTP_Proxy_Login . ':' . CONST_HTTP_Proxy_Password);
|
||||
$aHeaders = array("Proxy-Authorization: Basic $auth");
|
||||
}
|
||||
$aContext = array(
|
||||
'http' => array(
|
||||
'proxy' => $proxy,
|
||||
'request_fulluri' => true,
|
||||
'header' => $aHeaders
|
||||
),
|
||||
'https' => array(
|
||||
'proxy' => $proxy,
|
||||
'request_fulluri' => true,
|
||||
'header' => $aHeaders
|
||||
)
|
||||
);
|
||||
stream_context_set_default($aContext);
|
||||
}
|
||||
|
||||
47
lib/lib.php
47
lib/lib.php
@@ -39,6 +39,12 @@
|
||||
exit;
|
||||
}
|
||||
|
||||
function getParamBool($name, $default=false)
|
||||
{
|
||||
if (!isset($_GET[$name])) return $default;
|
||||
|
||||
return (bool) $_GET[$name];
|
||||
}
|
||||
|
||||
function fail($sError, $sUserError = false)
|
||||
{
|
||||
@@ -193,6 +199,26 @@
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
function getInverseWordSets($aWords, $iDepth)
|
||||
{
|
||||
$aResult = array(array(join(' ',$aWords)));
|
||||
$sFirstToken = '';
|
||||
if ($iDepth < 8)
|
||||
{
|
||||
while(sizeof($aWords) > 1)
|
||||
{
|
||||
$sWord = array_pop($aWords);
|
||||
$sFirstToken = $sWord.($sFirstToken?' ':'').$sFirstToken;
|
||||
$aRest = getInverseWordSets($aWords, $iDepth+1);
|
||||
foreach($aRest as $aSet)
|
||||
{
|
||||
$aResult[] = array_merge(array($sFirstToken),$aSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
|
||||
function getTokensFromSets($aSets)
|
||||
{
|
||||
@@ -358,7 +384,7 @@
|
||||
'landuse:farm' => array('label'=>'Farm','frequency'=>1201,'icon'=>'', 'defdiameter' => 0.02,),
|
||||
'place:farm' => array('label'=>'Farm','frequency'=>1162,'icon'=>'', 'defdiameter' => 0.02,),
|
||||
|
||||
'highway:motorway_junction' => array('label'=>'Motorway Junction','frequency'=>1126,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:motorway_junction' => array('label'=>'Motorway Junction','frequency'=>1126,'icon'=>'','simplelabel'=>'Junction',),
|
||||
'highway:motorway' => array('label'=>'Motorway','frequency'=>4627,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:trunk' => array('label'=>'Trunk','frequency'=>23084,'icon'=>'','simplelabel'=>'Road',),
|
||||
'highway:primary' => array('label'=>'Primary','frequency'=>32138,'icon'=>'','simplelabel'=>'Road',),
|
||||
@@ -418,7 +444,6 @@
|
||||
'tourism:hotel' => array('label'=>'Hotel','frequency'=>2150,'icon'=>'accommodation_hotel2',),
|
||||
'tourism:motel' => array('label'=>'Motel','frequency'=>43,'icon'=>'',),
|
||||
'amenity:cinema' => array('label'=>'Cinema','frequency'=>277,'icon'=>'tourist_cinema',),
|
||||
'tourism:information' => array('label'=>'Information','frequency'=>224,'icon'=>'amenity_information',),
|
||||
'tourism:artwork' => array('label'=>'Artwork','frequency'=>171,'icon'=>'tourist_art_gallery2',),
|
||||
'historic:archaeological_site' => array('label'=>'Archaeological Site','frequency'=>407,'icon'=>'tourist_archaeological2',),
|
||||
'amenity:doctors' => array('label'=>'Doctors','frequency'=>581,'icon'=>'health_doctors',),
|
||||
@@ -460,7 +485,7 @@
|
||||
'shop:electronics' => array('label'=>'Electronics','frequency'=>96,'icon'=>'',),
|
||||
'shop:department_store' => array('label'=>'Department Store','frequency'=>86,'icon'=>'',),
|
||||
'shop:books' => array('label'=>'Books','frequency'=>85,'icon'=>'',),
|
||||
'shop:yes' => array('label'=>'Yes','frequency'=>68,'icon'=>'',),
|
||||
'shop:yes' => array('label'=>'Shop','frequency'=>68,'icon'=>'',),
|
||||
'shop:outdoor' => array('label'=>'Outdoor','frequency'=>67,'icon'=>'',),
|
||||
'shop:mall' => array('label'=>'Mall','frequency'=>63,'icon'=>'',),
|
||||
'shop:florist' => array('label'=>'Florist','frequency'=>61,'icon'=>'',),
|
||||
@@ -492,6 +517,7 @@
|
||||
'shop:travel_agency' => array('label'=>'Travel Agency','frequency'=>21,'icon'=>'',),
|
||||
'shop:hifi' => array('label'=>'Hifi','frequency'=>21,'icon'=>'',),
|
||||
'amenity:shop' => array('label'=>'Shop','frequency'=>61,'icon'=>'',),
|
||||
'tourism:information' => array('label'=>'Information','frequency'=>224,'icon'=>'amenity_information',),
|
||||
|
||||
'place:house' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
|
||||
'place:house_name' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
|
||||
@@ -540,7 +566,6 @@
|
||||
'natural:beach' => array('label'=>'Beach','frequency'=>121,'icon'=>'tourist_beach',),
|
||||
'place:moor' => array('label'=>'Moor','frequency'=>118,'icon'=>'',),
|
||||
'amenity:grave_yard' => array('label'=>'Grave Yard','frequency'=>110,'icon'=>'',),
|
||||
'waterway:derelict_canal' => array('label'=>'Derelict Canal','frequency'=>109,'icon'=>'',),
|
||||
'waterway:drain' => array('label'=>'Drain','frequency'=>108,'icon'=>'',),
|
||||
'landuse:grass' => array('label'=>'Grass','frequency'=>106,'icon'=>'',),
|
||||
'landuse:village_green' => array('label'=>'Village Green','frequency'=>106,'icon'=>'',),
|
||||
@@ -606,7 +631,7 @@
|
||||
'historic:roman_road' => array('label'=>'Roman Road','frequency'=>27,'icon'=>'',),
|
||||
'historic:fort' => array('label'=>'Fort','frequency'=>26,'icon'=>'',),
|
||||
'railway:subway_entrance' => array('label'=>'Subway Entrance','frequency'=>26,'icon'=>'',),
|
||||
'historic:yes' => array('label'=>'Yes','frequency'=>25,'icon'=>'',),
|
||||
'historic:yes' => array('label'=>'Historic','frequency'=>25,'icon'=>'',),
|
||||
'highway:gate' => array('label'=>'Gate','frequency'=>25,'icon'=>'',),
|
||||
'leisure:fishing' => array('label'=>'Fishing','frequency'=>24,'icon'=>'',),
|
||||
'historic:museum' => array('label'=>'Museum','frequency'=>24,'icon'=>'',),
|
||||
@@ -628,7 +653,7 @@
|
||||
|
||||
'place:houses' => array('label'=>'Houses','frequency'=>85,'icon'=>'',),
|
||||
'railway:preserved' => array('label'=>'Preserved','frequency'=>227,'icon'=>'',),
|
||||
'waterway:derelict canal' => array('label'=>'Derelict Canal','frequency'=>21,'icon'=>'',),
|
||||
'waterway:derelict_canal' => array('label'=>'Derelict Canal','frequency'=>21,'icon'=>'',),
|
||||
'amenity:dead_pub' => array('label'=>'Dead Pub','frequency'=>20,'icon'=>'',),
|
||||
'railway:disused_station' => array('label'=>'Disused Station','frequency'=>114,'icon'=>'',),
|
||||
'railway:abandoned' => array('label'=>'Abandoned','frequency'=>641,'icon'=>'',),
|
||||
@@ -649,10 +674,12 @@
|
||||
}
|
||||
|
||||
|
||||
function javascript_renderData($xVal)
|
||||
function javascript_renderData($xVal, $iOptions = 0)
|
||||
{
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
$jsonout = json_encode($xVal);
|
||||
if (defined('PHP_VERSION_ID') && PHP_VERSION_ID > 50400)
|
||||
$iOptions |= JSON_UNESCAPED_UNICODE;
|
||||
$jsonout = json_encode($xVal, $iOptions);
|
||||
|
||||
if( ! isset($_GET['json_callback']))
|
||||
{
|
||||
@@ -943,7 +970,7 @@
|
||||
}
|
||||
// degrees decimal seconds
|
||||
// N 40 26 46 W 79 58 56
|
||||
// N 40° 26′ 46″ W, 79° 58′ 56″
|
||||
// N 40° 26′ 46″, W 79° 58′ 56″
|
||||
// 1 2 3 4 5 6 7 8
|
||||
elseif (preg_match('/\\b([NS])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*[, ]+([EW])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*\\b/', $sQuery, $aData))
|
||||
{
|
||||
@@ -994,4 +1021,4 @@
|
||||
$sQuery = trim(str_replace($sFound, ' ', $sQuery));
|
||||
|
||||
return array('lat' => $fQueryLat, 'lon' => $fQueryLon, 'query' => $sQuery);
|
||||
}
|
||||
}
|
||||
|
||||
129
lib/template/address-html.php
Normal file
129
lib/template/address-html.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
header("content-type: text/html; charset=UTF-8");
|
||||
?>
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
|
||||
<link href="css/common.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/search.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body id="reverse-page">
|
||||
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
|
||||
|
||||
<form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>reverse.php">
|
||||
<div class="form-group">
|
||||
<input name="format" type="hidden" value="html">
|
||||
<input name="lat" type="text" class="form-control input-sm" placeholder="latitude" value="<?php echo htmlspecialchars($_GET['lat']); ?>" >
|
||||
<input name="lon" type="text" class="form-control input-sm" placeholder="longitude" value="<?php echo htmlspecialchars($_GET['lon']); ?>" >
|
||||
max zoom
|
||||
|
||||
<select name="zoom" class="form-control input-sm" value="<?php echo htmlspecialchars($_GET['zoom']); ?>">
|
||||
<option value="" <?php echo $_GET['zoom']==''?'selected':'' ?> >--</option>
|
||||
<?php
|
||||
|
||||
$aZoomLevels = array(
|
||||
0 => "Continent / Sea",
|
||||
1 => "",
|
||||
2 => "",
|
||||
3 => "Country",
|
||||
4 => "",
|
||||
5 => "State",
|
||||
6 => "Region",
|
||||
7 => "",
|
||||
8 => "County",
|
||||
9 => "",
|
||||
10 => "City",
|
||||
11 => "",
|
||||
12 => "Town / Village",
|
||||
13 => "",
|
||||
14 => "Suburb",
|
||||
15 => "",
|
||||
16 => "Street",
|
||||
17 => "",
|
||||
18 => "Building",
|
||||
19 => "",
|
||||
20 => "",
|
||||
21 => "",
|
||||
);
|
||||
|
||||
foreach($aZoomLevels as $iZoomLevel => $sLabel)
|
||||
{
|
||||
$bSel = isset($_GET['zoom']) && ($_GET['zoom'] == (string)$iZoomLevel);
|
||||
echo '<option value="'.$iZoomLevel.'"'.($bSel?'selected':'').'>'.$iZoomLevel.' '.$sLabel.'</option>'."\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group search-button-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Search</button>
|
||||
</div>
|
||||
<div class="search-type-link">
|
||||
<a href="<?php echo CONST_Website_BaseURL; ?>search.php">forward search</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
<div id="content">
|
||||
|
||||
<?php if ($aPlace) { ?>
|
||||
|
||||
<div id="searchresults" class="sidebar">
|
||||
<?php
|
||||
$aResult = $aPlace;
|
||||
|
||||
echo '<div class="result" data-position="0">';
|
||||
|
||||
echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
|
||||
echo ' <span class="name">'.htmlspecialchars($aResult['langaddress']).'</span>';
|
||||
if (isset($aResult['label']))
|
||||
echo ' <span class="type">('.$aResult['label'].')</span>';
|
||||
else if ($aResult['type'] == 'yes')
|
||||
echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
|
||||
else
|
||||
echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
|
||||
echo '<p>'.$aResult['lat'].','.$aResult['lon'].'</p>';
|
||||
echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
|
||||
echo '</div>';
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php } else { ?>
|
||||
|
||||
<div id="intro" class="sidebar">
|
||||
Search for coordinates or click anywhere on the map.
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div id="map-wrapper">
|
||||
<div id="map-position"></div>
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
<?php
|
||||
|
||||
$aNominatimMapInit = array(
|
||||
'zoom' => isset($_GET['zoom']) ? htmlspecialchars($_GET['zoom']) : CONST_Default_Zoom,
|
||||
'lat' => isset($_GET['lat'] ) ? htmlspecialchars($_GET['lat'] ) : CONST_Default_Lat,
|
||||
'lon' => isset($_GET['lon'] ) ? htmlspecialchars($_GET['lon'] ) : CONST_Default_Lon,
|
||||
'tile_url' => $sTileURL,
|
||||
'tile_attribution' => $sTileAttribution
|
||||
);
|
||||
echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
|
||||
|
||||
echo 'var nominatim_results = ' . json_encode([$aPlace], JSON_PRETTY_PRINT) . ';';
|
||||
?>
|
||||
</script>
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($aPlace['place_id']) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
|
||||
if (isset($aPlace['place_id'])) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
|
||||
$aFilteredPlaces['licence'] = "Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
|
||||
$sOSMType = ($aPlace['osm_type'] == 'N'?'node':($aPlace['osm_type'] == 'W'?'way':($aPlace['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType)
|
||||
@@ -21,7 +21,9 @@
|
||||
if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
|
||||
if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
|
||||
$aFilteredPlaces['display_name'] = $aPlace['langaddress'];
|
||||
if ($bShowAddressDetails) $aFilteredPlaces['address'] = $aPlace['aAddress'];
|
||||
if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
|
||||
if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
|
||||
if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
|
||||
}
|
||||
|
||||
javascript_renderData($aFilteredPlaces);
|
||||
|
||||
@@ -23,16 +23,19 @@
|
||||
|
||||
$aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
|
||||
|
||||
$aFilteredPlaces['category'] = $aPlace['class'];
|
||||
$aFilteredPlaces['type'] = $aPlace['type'];
|
||||
$aFilteredPlaces['category'] = $aPlace['class'];
|
||||
$aFilteredPlaces['type'] = $aPlace['type'];
|
||||
|
||||
$aFilteredPlaces['importance'] = $aPlace['importance'];
|
||||
|
||||
$aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
|
||||
$aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
|
||||
|
||||
$aFilteredPlaces['display_name'] = $aPlace['langaddress'];
|
||||
$aFilteredPlaces['name'] = $aPlace['placename'];
|
||||
if ($bShowAddressDetails && $aPlace['aAddress'] && sizeof($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
|
||||
$aFilteredPlaces['name'] = $aPlace['placename'];
|
||||
|
||||
if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
|
||||
if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
|
||||
if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
|
||||
}
|
||||
|
||||
javascript_renderData($aFilteredPlaces);
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
if (isset($aPlace['lon'])) echo ' lon="'.htmlspecialchars($aPlace['lon']).'"';
|
||||
echo ">".htmlspecialchars($aPlace['langaddress'])."</result>";
|
||||
|
||||
if ($bShowAddressDetails) {
|
||||
if (isset($aPlace['aAddress']))
|
||||
{
|
||||
echo "<addressparts>";
|
||||
foreach($aPlace['aAddress'] as $sKey => $sValue)
|
||||
{
|
||||
@@ -40,6 +41,28 @@
|
||||
}
|
||||
echo "</addressparts>";
|
||||
}
|
||||
|
||||
if (isset($aPlace['sExtraTags']))
|
||||
{
|
||||
echo "<extratags>";
|
||||
foreach ($aPlace['sExtraTags'] as $sKey => $sValue)
|
||||
{
|
||||
echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
|
||||
}
|
||||
echo "</extratags>";
|
||||
}
|
||||
|
||||
if (isset($aPlace['sNameDetails']))
|
||||
{
|
||||
echo "<namedetails>";
|
||||
foreach ($aPlace['sNameDetails'] as $sKey => $sValue)
|
||||
{
|
||||
echo '<name desc="'.htmlspecialchars($sKey).'">';
|
||||
echo htmlspecialchars($sValue);
|
||||
echo "</name>";
|
||||
}
|
||||
echo "</namedetails>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</reversegeocode>";
|
||||
|
||||
@@ -1,180 +1,133 @@
|
||||
<?php
|
||||
header("content-type: text/html; charset=UTF-8");
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>OpenStreetMap Nominatim: <?php echo $aPointDetails['localname'];?></title>
|
||||
<style>
|
||||
body {
|
||||
margin:0px;
|
||||
padding:16px;
|
||||
background:#ffffff;
|
||||
height: 100%;
|
||||
font: normal 12px/15px arial,sans-serif;
|
||||
}
|
||||
.line{
|
||||
margin-left:20px;
|
||||
}
|
||||
.name{
|
||||
font-weight: bold;
|
||||
}
|
||||
.notused{
|
||||
color:#ddd;
|
||||
}
|
||||
.noname{
|
||||
color:#800;
|
||||
}
|
||||
#map {
|
||||
width:500px;
|
||||
height:500px;
|
||||
border: 2px solid #666;
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<script src="js/OpenLayers.js"></script>
|
||||
<script src="js/tiles.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map ("map", {
|
||||
controls:[
|
||||
new OpenLayers.Control.Permalink(),
|
||||
new OpenLayers.Control.Navigation(),
|
||||
new OpenLayers.Control.PanZoomBar(),
|
||||
new OpenLayers.Control.MouseDefaults(),
|
||||
new OpenLayers.Control.MousePosition(),
|
||||
new OpenLayers.Control.Attribution()],
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
|
||||
maxResolution: 156543.0399,
|
||||
numZoomLevels: 19,
|
||||
units: 'm',
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
displayProjection: new OpenLayers.Projection("EPSG:4326")
|
||||
} );
|
||||
map.addLayer(new OpenLayers.Layer.OSM.<?php echo CONST_Tile_Default;?>("Default"));
|
||||
|
||||
var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
|
||||
layer_style.fillOpacity = 0.2;
|
||||
layer_style.graphicOpacity = 0.2;
|
||||
|
||||
vectorLayer = new OpenLayers.Layer.Vector("Points", {style: layer_style});
|
||||
map.addLayer(vectorLayer);
|
||||
|
||||
var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
||||
var proj_map = map.getProjectionObject();
|
||||
|
||||
freader = new OpenLayers.Format.WKT({
|
||||
'internalProjection': proj_map,
|
||||
'externalProjection': proj_EPSG4326
|
||||
});
|
||||
|
||||
var bounds;
|
||||
<?php if ($aPointDetails['prevgeom']) { ?>
|
||||
var feature = freader.read('<?php echo $aPointDetails['prevgeom'];?>');
|
||||
if (feature) {
|
||||
bounds = feature.geometry.getBounds();
|
||||
|
||||
}
|
||||
feature.style = {
|
||||
strokeColor: "#777777",
|
||||
fillColor: "#F0F0F0",
|
||||
strokeWidth: 2,
|
||||
strokeOpacity: 0.75,
|
||||
fillOpacity: 0.75,
|
||||
strokeDashstyle: "longdash"
|
||||
};
|
||||
vectorLayer.addFeatures([feature]);
|
||||
<?php } ?>
|
||||
|
||||
<?php if ($aPointDetails['newgeom']) { ?>
|
||||
feature = freader.read('<?php echo $aPointDetails['newgeom'];?>');
|
||||
if (feature) {
|
||||
if (!bounds) {
|
||||
bounds = feature.geometry.getBounds();
|
||||
}
|
||||
else
|
||||
{
|
||||
bounds.extend(feature.geometry.getBounds());
|
||||
}
|
||||
}
|
||||
feature.style = {
|
||||
strokeColor: "#75ADFF",
|
||||
fillColor: "#FFF7F0",
|
||||
strokeWidth: 2,
|
||||
strokeOpacity: 0.75,
|
||||
fillOpacity: 0.75
|
||||
};
|
||||
vectorLayer.addFeatures([feature]);
|
||||
<?php } ?>
|
||||
|
||||
<?php if (isset($aPointDetails['error_x'])) { ?>
|
||||
var pt = new OpenLayers.Geometry.Point(<?php echo $aPointDetails['error_x'].','.$aPointDetails['error_y'];?>);
|
||||
pt = pt.transform(proj_EPSG4326, proj_map);
|
||||
feature = new OpenLayers.Feature.Vector(pt, null,
|
||||
{
|
||||
graphicName : "x",
|
||||
fillColor: "#FF0000",
|
||||
graphic : true,
|
||||
pointRadius: 6
|
||||
});
|
||||
vectorLayer.addFeatures([feature]);
|
||||
<?php } ?>
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
|
||||
<link href="css/common.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/details.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
|
||||
map.zoomToExtent(bounds);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<div id="map"></div>
|
||||
<h1><?php echo $aPointDetails['localname'] ?></h1>
|
||||
<div class="locationdetails">
|
||||
<div>Type: <span class="type"><?php echo $aPointDetails['class'].':'.$aPointDetails['type'];?></span></div>
|
||||
|
||||
<?php
|
||||
$sOSMType = ($aPointDetails['osm_type'] == 'N'?'node':($aPointDetails['osm_type'] == 'W'?'way': ($aPointDetails['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType) echo ' <div>OSM: <span class="osm"><span class="label"></span>'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aPointDetails['osm_id'].'">'. $aPointDetails['osm_id'].'</a></span></div>';
|
||||
|
||||
function osm_link($aFeature)
|
||||
{
|
||||
$sOSMType = ($aFeature['osm_type'] == 'N'?'node':($aFeature['osm_type'] == 'W'?'way':($aFeature['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType) {
|
||||
return '<a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aFeature['osm_id'].'">'.$sOSMType.' '.$aFeature['osm_id'].'</a>';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function osm_map_url($aFeature)
|
||||
{
|
||||
$sLon = $aFeature['error_x'];
|
||||
$sLat = $aFeature['error_y'];
|
||||
|
||||
if (isset($sLat))
|
||||
{
|
||||
$sOSMType = ($aFeature['osm_type'] == 'N'?'node':($aFeature['osm_type'] == 'W'?'way':($aFeature['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType)
|
||||
{
|
||||
return "http://www.openstreetmap.org/?lat=".$sLat."&lon=".$sLon."&zoom=18&layers=M&".$sOSMType."=".$aFeature['osm_id'];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function josm_edit_url($aFeature)
|
||||
{
|
||||
$fWidth = 0.0002;
|
||||
$sLon = $aFeature['error_x'];
|
||||
$sLat = $aFeature['error_y'];
|
||||
|
||||
if (isset($sLat))
|
||||
{
|
||||
return "http://localhost:8111/load_and_zoom?left=".($sLon-$fWidth)."&right=".($sLon+$fWidth)."&top=".($sLat+$fWidth)."&bottom=".($sLat-$fWidth);
|
||||
}
|
||||
|
||||
$sOSMType = ($aFeature['osm_type'] == 'N'?'node':($aFeature['osm_type'] == 'W'?'way':($aFeature['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType)
|
||||
{
|
||||
return 'http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/'.$sOSMType.'/'.$aFeature['osm_id'].'/full';
|
||||
// Should be better to load by object id - but this doesn't seem to zoom correctly
|
||||
// return " <a href=\"http://localhost:8111/load_object?new_layer=true&objects=".strtolower($aFeature['osm_type']).$sOSMID."\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function potlach_edit_url($aFeature)
|
||||
{
|
||||
$fWidth = 0.0002;
|
||||
$sLat = $aFeature['error_y'];
|
||||
$sLon = $aFeature['error_x'];
|
||||
|
||||
if (isset($sLat))
|
||||
{
|
||||
return "http://www.openstreetmap.org/edit?editor=potlatch2&bbox=".($sLon-$fWidth).",".($sLat-$fWidth).",".($sLon+$fWidth).",".($sLat+$fWidth);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<p>This object has an invalid geometry.</p>
|
||||
<p><b>Details:</b> <?php
|
||||
<body id="details-page">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
||||
$sVal = $aPointDetails['errormessage']?$aPointDetails['errormessage']:' ';
|
||||
$sOSMType = ($aPointDetails['osm_type'] == 'N'?'node':($aPointDetails['osm_type'] == 'W'?'way':($aPointDetails['osm_type'] == 'R'?'relation':'')));
|
||||
$sOSMID = $aPointDetails['osm_id'];
|
||||
|
||||
if (isset($aPointDetails['error_x']))
|
||||
{
|
||||
$sLat = $aPointDetails['error_y'];
|
||||
$sLon = $aPointDetails['error_x'];
|
||||
echo "<a href=\"http://www.openstreetmap.org/?lat=".$sLat."&lon=".$sLon."&zoom=18&layers=M&".$sOSMType."=".$sOSMID."\">".$sVal."</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo $sVal;
|
||||
}
|
||||
?>
|
||||
<p><b>Edit:</b> in <?php
|
||||
if (isset($aPointDetails['error_x']))
|
||||
{
|
||||
$fWidth = 0.0002;
|
||||
echo " <a href=\"http://localhost:8111/load_and_zoom?left=".($sLon-$fWidth)."&right=".($sLon+$fWidth)."&top=".($sLat+$fWidth)."&bottom=".($sLat-$fWidth)."\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
|
||||
echo " | <a href=\"http://www.openstreetmap.org/edit?editor=potlatch2&bbox=".($sLon-$fWidth).",".($sLat-$fWidth).",".($sLon+$fWidth).",".($sLat+$fWidth)."\" target=\"potlatch2\">Potlatch 2</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " <a href=\"http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/".$sOSMType.'/'.$sOSMID."/full\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
|
||||
// Should be better to load by object id - but this doesn't seem to zoom correctly
|
||||
//echo " <a href=\"http://localhost:8111/load_object?new_layer=true&objects=".strtolower($aPointDetails['osm_type']).$sOSMID."\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
|
||||
}
|
||||
<h1><?php echo $aPointDetails['localname'] ?></h1>
|
||||
<div class="locationdetails">
|
||||
<h2 class="bg-danger">This object has an invalid geometry.</h2>
|
||||
|
||||
?></p>
|
||||
<div>
|
||||
Type: <span class="type"><?php echo $aPointDetails['class'].':'.$aPointDetails['type'];?></span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<div>
|
||||
OSM: <span class="label"><?php echo osm_link($aPointDetails); ?><span>
|
||||
</div>
|
||||
|
||||
|
||||
<h4>Error</h4>
|
||||
<p>
|
||||
<?php echo $aPointDetails['errormessage']?$aPointDetails['errormessage']:'unknown'; ?>
|
||||
</p>
|
||||
<?php if (osm_map_url($aPointDetails)) { ?>
|
||||
<a href="<?php echo osm_map_url($aPointDetails); ?>">view on osm.org</a>
|
||||
<?php } ?>
|
||||
|
||||
<h4>Edit</h4>
|
||||
<ul>
|
||||
<?php if (josm_edit_url($aPointDetails)) { ?>
|
||||
<li><a href="<?php echo josm_edit_url($aPointDetails); ?>" target="josm">Remote Control (JOSM / Merkaartor)</a></li>
|
||||
<?php } ?>
|
||||
<?php if (potlach_edit_url($aPointDetails)) { ?>
|
||||
<li><a href="<?php echo potlach_edit_url($aPointDetails); ?>" target="potlatch2">Potlatch 2</a></li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var nominatim_result = {
|
||||
outlinestring: '<?php echo $aPointDetails['outlinestring'];?>',
|
||||
lon: <?php echo isset($aPointDetails['error_x']) ? $aPointDetails['error_x'] : 0; ?>,
|
||||
lat: <?php echo isset($aPointDetails['error_y']) ? $aPointDetails['error_y'] : 0; ?>
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,226 +1,301 @@
|
||||
<?php
|
||||
header("content-type: text/html; charset=UTF-8");
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>OpenStreetMap Nominatim: <?php echo $aPointDetails['localname'];?></title>
|
||||
<link href="css/details.css" rel="stylesheet" type="text/css" />
|
||||
<script src="js/OpenLayers.js" type="text/javascript"></script>
|
||||
<script src="js/tiles.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
|
||||
<link href="css/common.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/details.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
var map;
|
||||
|
||||
function init() {
|
||||
map = new OpenLayers.Map ("map", {
|
||||
controls:[
|
||||
new OpenLayers.Control.Permalink(),
|
||||
new OpenLayers.Control.Navigation(),
|
||||
new OpenLayers.Control.PanZoomBar(),
|
||||
new OpenLayers.Control.MousePosition(),
|
||||
new OpenLayers.Control.Attribution()],
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
|
||||
maxResolution: 156543.0399,
|
||||
numZoomLevels: 19,
|
||||
units: 'm',
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
displayProjection: new OpenLayers.Projection("EPSG:4326")
|
||||
} );
|
||||
map.addLayer(new OpenLayers.Layer.OSM.<?php echo CONST_Tile_Default;?>("Default"));
|
||||
|
||||
var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
|
||||
layer_style.fillOpacity = 0.2;
|
||||
layer_style.graphicOpacity = 0.2;
|
||||
|
||||
vectorLayer = new OpenLayers.Layer.Vector("Points", {style: layer_style});
|
||||
map.addLayer(vectorLayer);
|
||||
|
||||
var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
||||
var proj_map = map.getProjectionObject();
|
||||
|
||||
freader = new OpenLayers.Format.WKT({
|
||||
'internalProjection': proj_map,
|
||||
'externalProjection': proj_EPSG4326
|
||||
});
|
||||
|
||||
var feature = freader.read('<?php echo $aPointDetails['outlinestring'];?>');
|
||||
var featureCentre = freader.read('POINT(<?php echo $aPointDetails['lon'];?> <?php echo $aPointDetails['lat'];?>)');
|
||||
if (feature) {
|
||||
map.zoomToExtent(feature.geometry.getBounds());
|
||||
feature.style = {
|
||||
strokeColor: "#75ADFF",
|
||||
fillColor: "#F0F7FF",
|
||||
strokeWidth: <?php echo ($aPointDetails['isarea']=='t'?'2':'5');?>,
|
||||
strokeOpacity: 0.75,
|
||||
fillOpacity: 0.75,
|
||||
pointRadius: 50
|
||||
};
|
||||
|
||||
<?php if ($aPointDetails['isarea']=='t') {?>
|
||||
featureCentre.style = {
|
||||
strokeColor: "#008800",
|
||||
fillColor: "#338833",
|
||||
strokeWidth: <?php echo ($aPointDetails['isarea']=='t'?'2':'5');?>,
|
||||
strokeOpacity: 0.75,
|
||||
fillOpacity: 0.75,
|
||||
pointRadius: 8
|
||||
};
|
||||
vectorLayer.addFeatures([feature,featureCentre]);
|
||||
<?php } else { ?>
|
||||
vectorLayer.addFeatures([feature]);
|
||||
<?php } ?>
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<div id="map"></div>
|
||||
<?php
|
||||
echo '<h1>';
|
||||
if ($aPointDetails['icon'])
|
||||
{
|
||||
echo '<img style="float:right;margin-right:40px;" src="'.CONST_Website_BaseURL.'images/mapicons/'.$aPointDetails['icon'].'.n.32.png'.'" alt="'.$aPointDetails['icon'].'" />';
|
||||
}
|
||||
echo $aPointDetails['localname']."</h1>\n";
|
||||
echo '<div class="locationdetails">';
|
||||
echo ' <div>Name: ';
|
||||
foreach($aPointDetails['aNames'] as $sKey => $sValue)
|
||||
{
|
||||
echo ' <div class="line"><span class="name">'.$sValue.'</span> ('.$sKey.')</div>';
|
||||
}
|
||||
echo ' </div>';
|
||||
echo ' <div>Type: <span class="type">'.$aPointDetails['class'].':'.$aPointDetails['type'].'</span></div>';
|
||||
echo ' <div>Last Updated: <span class="type">'.$aPointDetails['indexed_date'].'</span></div>';
|
||||
echo ' <div>Admin Level: <span class="adminlevel">'.$aPointDetails['admin_level'].'</span></div>';
|
||||
echo ' <div>Rank: <span class="rankaddress">'.$aPointDetails['rank_search_label'].'</span></div>';
|
||||
if ($aPointDetails['calculated_importance']) echo ' <div>Importance: <span class="rankaddress">'.$aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)').'</span></div>';
|
||||
echo ' <div>Coverage: <span class="area">'.($aPointDetails['isarea']=='t'?'Polygon':'Point').'</span></div>';
|
||||
echo ' <div>Centre Point: <span class="area">'.$aPointDetails['lat'].','.$aPointDetails['lon'].'</span></div>';
|
||||
$sOSMType = ($aPointDetails['osm_type'] == 'N'?'node':($aPointDetails['osm_type'] == 'W'?'way':($aPointDetails['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType) echo ' <div>OSM: <span class="osm">'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aPointDetails['osm_id'].'">'.$aPointDetails['osm_id'].'</a></span></div>';
|
||||
if ($aPointDetails['wikipedia'])
|
||||
{
|
||||
list($sWikipediaLanguage,$sWikipediaArticle) = explode(':',$aPointDetails['wikipedia']);
|
||||
echo ' <div>Wikipedia Calculated: <span class="wikipedia"><a href="http://'.$sWikipediaLanguage.'.wikipedia.org/wiki/'.urlencode($sWikipediaArticle).'">'.$aPointDetails['wikipedia'].'</a></span></div>';
|
||||
}
|
||||
echo ' <div>Extra Tags: ';
|
||||
foreach($aPointDetails['aExtraTags'] as $sKey => $sValue)
|
||||
{
|
||||
echo ' <div class="line"><span class="name">'.$sValue.'</span> ('.$sKey.')</div>';
|
||||
}
|
||||
echo ' </div>';
|
||||
echo "</div>\n";
|
||||
|
||||
echo "<h2>Address</h2>\n";
|
||||
echo '<div class="address">';
|
||||
$iPrevRank = 1000000;
|
||||
$sPrevLocalName = '';
|
||||
foreach($aAddressLines as $aAddressLine)
|
||||
{
|
||||
$sOSMType = ($aAddressLine['osm_type'] == 'N'?'node':($aAddressLine['osm_type'] == 'W'?'way':($aAddressLine['osm_type'] == 'R'?'relation':'')));
|
||||
function headline($sTitle)
|
||||
{
|
||||
echo "<tr class='all-columns'><td colspan='6'><h2>".$sTitle."</h2></td></tr>\n";
|
||||
}
|
||||
|
||||
echo '<div class="line'.($aAddressLine['isaddress']=='f'?' notused':'').'">';
|
||||
if (!($iPrevRank<=$aAddressLine['rank_address'] || $sPrevLocalName == $aAddressLine['localname']))
|
||||
function headline3($sTitle)
|
||||
{
|
||||
echo "<tr class='all-columns'><td colspan='6'><h3>".$sTitle."</h3></td></tr>\n";
|
||||
}
|
||||
|
||||
function osm_link($aFeature)
|
||||
{
|
||||
$sOSMType = ($aFeature['osm_type'] == 'N'?'node':($aFeature['osm_type'] == 'W'?'way':($aFeature['osm_type'] == 'R'?'relation':'')));
|
||||
if ($sOSMType)
|
||||
{
|
||||
$iPrevRank = $aAddressLine['rank_address'];
|
||||
$sPrevLocalName = $aAddressLine['localname'];
|
||||
return '<a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aFeature['osm_id'].'">'.$sOSMType.' '.$aFeature['osm_id'].'</a>';
|
||||
}
|
||||
echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
|
||||
echo ' (';
|
||||
echo '<span class="type"><span class="label">Type: </span>'.$aAddressLine['class'].':'.$aAddressLine['type'].'</span>';
|
||||
if ($sOSMType) echo ', <span class="osm">'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></span>';
|
||||
if (isset($aAddressLine['admin_level'])) echo ', <span class="adminlevel">'.$aAddressLine['admin_level'].'</span>';
|
||||
if (isset($aAddressLine['rank_search_label'])) echo ', <span class="rankaddress">'.$aAddressLine['rank_search_label'].'</span>';
|
||||
// echo ', <span class="area">'.($aAddressLine['fromarea']=='t'?'Polygon':'Point').'</span>';
|
||||
echo ', <span class="distance">'.$aAddressLine['distance'].'</span>';
|
||||
echo ' <a href="details.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
|
||||
echo ')';
|
||||
echo "</div>\n";
|
||||
return '';
|
||||
}
|
||||
echo "</div>\n";
|
||||
|
||||
function wikipedia_link($aFeature)
|
||||
{
|
||||
if ($aFeature['wikipedia'])
|
||||
{
|
||||
list($sWikipediaLanguage,$sWikipediaArticle) = explode(':',$aFeature['wikipedia']);
|
||||
return '<a href="https://'.$sWikipediaLanguage.'.wikipedia.org/wiki/'.urlencode($sWikipediaArticle).'" target="_blank">'.$aFeature['wikipedia'].'</a>';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function nominatim_link($aFeature, $sTitle)
|
||||
{
|
||||
return '<a href="details.php?place_id='.$aFeature['place_id'].'">'.$sTitle.'</a>';
|
||||
}
|
||||
|
||||
function format_distance($fDistance)
|
||||
{
|
||||
// $fDistance is in meters
|
||||
if ($fDistance < 1)
|
||||
{
|
||||
return '0';
|
||||
}
|
||||
elseif ($fDistance < 1000)
|
||||
{
|
||||
return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance,0)).' m</abbr>';
|
||||
}
|
||||
else
|
||||
{
|
||||
return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance/1000,1)).' km</abbr>';
|
||||
}
|
||||
}
|
||||
|
||||
function kv($sKey,$sValue)
|
||||
{
|
||||
echo ' <tr><td>' . $sKey . '</td><td>'.$sValue.'</td></tr>'. "\n";
|
||||
}
|
||||
|
||||
|
||||
function hash_to_subtable($aAssociatedList)
|
||||
{
|
||||
$sHTML = '';
|
||||
foreach($aAssociatedList as $sKey => $sValue)
|
||||
{
|
||||
$sHTML = $sHTML.' <div class="line"><span class="name">'.$sValue.'</span> ('.$sKey.')</div>'."\n";
|
||||
}
|
||||
return $sHTML;
|
||||
}
|
||||
|
||||
// function hash_to_subtable($aAssociatedList)
|
||||
// {
|
||||
// $sHTML = '<table class="table">';
|
||||
// foreach($aAssociatedList as $sKey => $sValue)
|
||||
// {
|
||||
// $sHTML = $sHTML . '<tr><td>'.$sKey.'</td><td class="name">'.$sValue.'</td></tr>'."\n";
|
||||
// }
|
||||
// $sHTML = $sHTML . '</table>';
|
||||
// return $sHTML;
|
||||
// }
|
||||
|
||||
|
||||
function map_icon($sIcon)
|
||||
{
|
||||
if ($sIcon){
|
||||
echo '<img id="mapicon" src="'.CONST_Website_BaseURL.'images/mapicons/'.$sIcon.'.n.32.png'.'" alt="'.$sIcon.'" />';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _one_row($aAddressLine){
|
||||
$bNotUsed = (isset($aAddressLine['isaddress']) && $aAddressLine['isaddress'] == 'f');
|
||||
|
||||
echo '<tr class="' . ($bNotUsed?'notused':'') . '">'."\n";
|
||||
echo ' <td class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>')."</td>\n";
|
||||
echo ' <td>' . $aAddressLine['class'].':'.$aAddressLine['type'] . "</td>\n";
|
||||
echo ' <td>' . osm_link($aAddressLine) . "</td>\n";
|
||||
echo ' <td>' . (isset($aAddressLine['admin_level']) ? $aAddressLine['admin_level'] : '') . "</td>\n";
|
||||
// echo '<td>' . (isset($aAddressLine['rank_search_label']) ? $aAddressLine['rank_search_label'] : '') ."</td>\n";
|
||||
// echo ', <span class="area">'.($aAddressLine['fromarea']=='t'?'Polygon':'Point').'</span>';
|
||||
echo ' <td>' . format_distance($aAddressLine['distance'])."</td>\n";
|
||||
echo ' <td>' . nominatim_link($aAddressLine,'details >') . "</td>\n";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
|
||||
function _one_keyword_row($keyword_token,$word_id){
|
||||
echo "<tr>\n";
|
||||
echo '<td>';
|
||||
// mark partial tokens (those starting with a space) with a star for readability
|
||||
echo ($keyword_token[0]==' '?'*':'');
|
||||
echo $keyword_token;
|
||||
if (isset($word_id))
|
||||
{
|
||||
echo '</td><td>word id: '.$word_id;
|
||||
}
|
||||
echo "</td></tr>\n";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<body id="details-page">
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-10">
|
||||
<h1><?php echo $aPointDetails['localname'] ?></h1>
|
||||
</div>
|
||||
<div class="col-sm-2 text-right">
|
||||
<?php map_icon($aPointDetails['icon']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table id="locationdetails" class="table table-striped">
|
||||
|
||||
<?php
|
||||
|
||||
kv('Name' , hash_to_subtable($aPointDetails['aNames']) );
|
||||
kv('Type' , $aPointDetails['class'].':'.$aPointDetails['type'] );
|
||||
kv('Last Updated' , $aPointDetails['indexed_date'] );
|
||||
kv('Admin Level' , $aPointDetails['admin_level'] );
|
||||
kv('Rank' , $aPointDetails['rank_search_label'] );
|
||||
if ($aPointDetails['calculated_importance']) {
|
||||
kv('Importance' , $aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)') );
|
||||
}
|
||||
kv('Coverage' , ($aPointDetails['isarea']=='t'?'Polygon':'Point') );
|
||||
kv('Centre Point' , $aPointDetails['lat'].','.$aPointDetails['lon'] );
|
||||
kv('OSM' , osm_link($aPointDetails) );
|
||||
if ($aPointDetails['wikipedia'])
|
||||
{
|
||||
kv('Wikipedia Calculated' , wikipedia_link($aPointDetails) );
|
||||
}
|
||||
|
||||
kv('Extra Tags' , hash_to_subtable($aPointDetails['aExtraTags']) );
|
||||
|
||||
?>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
<h2>Address</h2>
|
||||
|
||||
<table id="address" class="table table-striped table-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Local name</td>
|
||||
<td>Type</td>
|
||||
<td>OSM</td>
|
||||
<td>Admin level</td>
|
||||
<!-- <td>Search rank</td> -->
|
||||
<td>Distance</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php
|
||||
|
||||
foreach($aAddressLines as $aAddressLine)
|
||||
{
|
||||
_one_row($aAddressLine);
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
|
||||
if ($aLinkedLines)
|
||||
{
|
||||
echo "<h2>Linked Places</h2>\n";
|
||||
echo '<div class="linked">';
|
||||
headline('Linked Places');
|
||||
foreach($aLinkedLines as $aAddressLine)
|
||||
{
|
||||
$sOSMType = ($aAddressLine['osm_type'] == 'N'?'node':($aAddressLine['osm_type'] == 'W'?'way':($aAddressLine['osm_type'] == 'R'?'relation':'')));
|
||||
|
||||
echo '<div class="line">';
|
||||
echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
|
||||
echo ' (';
|
||||
echo '<span class="type"><span class="label">Type: </span>'.$aAddressLine['class'].':'.$aAddressLine['type'].'</span>';
|
||||
if ($sOSMType) echo ', <span class="osm">'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></span>';
|
||||
echo ', <span class="adminlevel">'.$aAddressLine['admin_level'].'</span>';
|
||||
if (isset($aAddressLine['rank_search_label'])) echo ', <span class="rankaddress">'.$aAddressLine['rank_search_label'].'</span>';
|
||||
// echo ', <span class="area">'.($aAddressLine['fromarea']=='t'?'Polygon':'Point').'</span>';
|
||||
echo ', <span class="distance">'.$aAddressLine['distance'].'</span>';
|
||||
echo ' <a href="details.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
|
||||
echo ')';
|
||||
echo "</div>\n";
|
||||
_one_row($aAddressLine);
|
||||
}
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($aPlaceSearchNameKeywords)
|
||||
{
|
||||
echo '<h2>Name Keywords</h2>';
|
||||
headline('Name Keywords');
|
||||
foreach($aPlaceSearchNameKeywords as $aRow)
|
||||
{
|
||||
echo '<div>'.$aRow['word_token']."</div>\n";
|
||||
_one_keyword_row($aRow['word_token'], $aRow['word_id']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($aPlaceSearchAddressKeywords)
|
||||
{
|
||||
echo '<h2>Address Keywords</h2>';
|
||||
headline('Address Keywords');
|
||||
foreach($aPlaceSearchAddressKeywords as $aRow)
|
||||
{
|
||||
echo '<div>'.($aRow['word_token'][0]==' '?'*':'').$aRow['word_token'].'('.$aRow['word_id'].')'."</div>\n";
|
||||
_one_keyword_row($aRow['word_token'], $aRow['word_id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (sizeof($aParentOfLines))
|
||||
{
|
||||
echo "<h2>Parent Of:</h2>\n<div>\n";
|
||||
headline('Parent Of');
|
||||
|
||||
$aGroupedAddressLines = array();
|
||||
foreach($aParentOfLines as $aAddressLine)
|
||||
{
|
||||
if (!isset($aGroupedAddressLines[$aAddressLine['type']])) $aGroupedAddressLines[$aAddressLine['type']] = array();
|
||||
$aGroupedAddressLines[$aAddressLine['type']][] = $aAddressLine;
|
||||
if ($aAddressLine['type'] == 'yes') $sType = $aAddressLine['class'];
|
||||
else $sType = $aAddressLine['type'];
|
||||
|
||||
if (!isset($aGroupedAddressLines[$sType]))
|
||||
$aGroupedAddressLines[$sType] = array();
|
||||
$aGroupedAddressLines[$sType][] = $aAddressLine;
|
||||
}
|
||||
foreach($aGroupedAddressLines as $sGroupHeading => $aParentOfLines)
|
||||
{
|
||||
$sGroupHeading = ucwords($sGroupHeading);
|
||||
echo "<h3>$sGroupHeading</h3>\n";
|
||||
foreach($aParentOfLines as $aAddressLine)
|
||||
{
|
||||
$aAddressLine['localname'] = $aAddressLine['localname']?$aAddressLine['localname']:$aAddressLine['housenumber'];
|
||||
$sOSMType = ($aAddressLine['osm_type'] == 'N'?'node':($aAddressLine['osm_type'] == 'W'?'way':($aAddressLine['osm_type'] == 'R'?'relation':'')));
|
||||
|
||||
echo '<div class="line">';
|
||||
echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
|
||||
echo ' (';
|
||||
echo '<span class="area">'.($aAddressLine['isarea']=='t'?'Polygon':'Point').'</span>';
|
||||
echo ', <span class="distance">~'.(round($aAddressLine['distance']*69,1)).' miles</span>';
|
||||
if ($sOSMType) echo ', <span class="osm">'.$sOSMType.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></span>';
|
||||
echo ', <a href="details.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
|
||||
echo ')';
|
||||
echo "</div>\n";
|
||||
}
|
||||
headline3($sGroupHeading);
|
||||
|
||||
foreach($aParentOfLines as $aAddressLine)
|
||||
{
|
||||
_one_row($aAddressLine);
|
||||
}
|
||||
}
|
||||
if (sizeof($aParentOfLines) >= 500) {
|
||||
echo '<p>There are more child objects which are not shown.</p>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
// echo '<h2>Other Parts:</h2>';
|
||||
// echo '<h2>Linked To:</h2>';
|
||||
// headline('Other Parts');
|
||||
// headline('Linked To');
|
||||
|
||||
echo "</table>\n";
|
||||
?>
|
||||
|
||||
</body>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
<?php
|
||||
|
||||
$aNominatimMapInit = array(
|
||||
'tile_url' => $sTileURL,
|
||||
'tile_attribution' => $sTileAttribution
|
||||
);
|
||||
echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
|
||||
|
||||
$aPlace = array(
|
||||
'outlinestring' => $aPointDetails['outlinestring'],
|
||||
'lon' => $aPointDetails['lon'],
|
||||
'lat' => $aPointDetails['lat'],
|
||||
);
|
||||
echo 'var nominatim_result = ' . json_encode($aPlace, JSON_PRETTY_PRINT) . ';';
|
||||
|
||||
|
||||
?>
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
14
lib/template/includes/html-footer.php
Normal file
14
lib/template/includes/html-footer.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<footer>
|
||||
<p class="disclaimer">
|
||||
Addresses and postcodes are approximate
|
||||
</p>
|
||||
<p class="copyright">
|
||||
© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<script src="js/leaflet.min.js"></script>
|
||||
<script src="js/leaflet-omnivore.min.js"></script>
|
||||
<script src="js/nominatim-ui.js"></script>
|
||||
11
lib/template/includes/html-header.php
Normal file
11
lib/template/includes/html-header.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>OpenStreetMap Nominatim: Search</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<base href="<?php echo CONST_Website_BaseURL;?>" />
|
||||
<link href="nominatim.xml" rel="search" title="Nominatim Search" type="application/opensearchdescription+xml" />
|
||||
<link href="css/leaflet.css" rel="stylesheet" />
|
||||
<link href="css/bootstrap-theme.min.css" rel="stylesheet" />
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet" />
|
||||
49
lib/template/includes/html-top-navigation.php
Normal file
49
lib/template/includes/html-top-navigation.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<header class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-xs-4">
|
||||
<div class="brand">
|
||||
<a href="<?php echo CONST_Website_BaseURL;?>">
|
||||
<img alt="logo" src="images/osm_logo.120px.png" width="30" height="30"/>
|
||||
<h1>Nominatim</h1>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="last-updated" class="col-xs-4 text-center">
|
||||
<?php if (isset($sDataDate)){ ?>
|
||||
Data last updated:
|
||||
<br>
|
||||
<?php echo $sDataDate; ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="col-xs-4 text-right">
|
||||
<div class="btn-group">
|
||||
<button class="dropdown-toggle btn btn-sm btn-default" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
About & Help <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<li><a href="http://wiki.openstreetmap.org/wiki/Nominatim" target="_blank">Documentation</a></li>
|
||||
<li><a href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ" target="_blank">FAQ</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a href="#" class="" data-toggle="modal" data-target="#report-modal">Report problem with results</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="modal fade" id="report-modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Report a problem</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/report-errors.php'); ?>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
9
lib/template/includes/introduction.php
Normal file
9
lib/template/includes/introduction.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<h2>Welcome to Nominatim</h2>
|
||||
|
||||
<p>Nominatim is a search engine for <a href="http://www.openstreetmap.org">OpenStreetMap</a>
|
||||
data. This is the debugging interface. You may search for a name or address(forward search) or
|
||||
look up data by its geographic coordinate(reverse search). Each result comes with a
|
||||
link to a details page where you can inspect what data about the object is saved in
|
||||
the database and investigate how the address of the object has been computed.</p>
|
||||
|
||||
For more information visit the <a href="http://wiki.openstreetmap.org/wiki/Nominatim">Nominatim wiki page</a>.
|
||||
24
lib/template/includes/report-errors.php
Normal file
24
lib/template/includes/report-errors.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<p>
|
||||
Before reporting problems please read the <a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim">user documentation</a>
|
||||
and
|
||||
<a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ">FAQ</a>.
|
||||
|
||||
If your problem relates to the address of a particular search result please use the 'details' link
|
||||
to check how the address was generated before reporting a problem.
|
||||
</p>
|
||||
<p>
|
||||
Use <a target="_blank" href="https://github.com/twain47/nominatim/issues">Nominatim issues on github</a>
|
||||
to report problems.
|
||||
<!-- You can search for existing bug reports
|
||||
<a href="http://trac.openstreetmap.org/query?status=new&status=assigned&status=reopened&component=nominatim&order=priority">here</a>.</p>
|
||||
-->
|
||||
</p>
|
||||
<p>
|
||||
Please ensure that you include a full description of the problem, including the search
|
||||
query that you used, the problem with the result and, if the problem relates to missing data,
|
||||
the osm type (node, way, relation) and id of the item that is missing.
|
||||
</p>
|
||||
<p>
|
||||
Problems that contain enough detail are likely to get looked at before ones that require
|
||||
significant research.
|
||||
</p>
|
||||
@@ -1,298 +1,114 @@
|
||||
<?php
|
||||
header("content-type: text/html; charset=UTF-8");
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>OpenStreetMap Nominatim: Search</title>
|
||||
|
||||
<base href="<?php echo CONST_Website_BaseURL;?>" />
|
||||
<link href="nominatim.xml" rel="search" title="Nominatim Search" type="application/opensearchdescription+xml" />
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
|
||||
<link href="css/common.css" rel="stylesheet" type="text/css" />
|
||||
<link href="css/search.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="js/OpenLayers.js" type="text/javascript"></script>
|
||||
<script src="js/tiles.js" type="text/javascript"></script>
|
||||
<script src="js/prototype-1.6.0.3.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var map;
|
||||
|
||||
function handleResize()
|
||||
{
|
||||
if ($('searchresults'))
|
||||
{
|
||||
var viewwidth = ((document.documentElement.clientWidth > 0?document.documentElement.clientWidth:document.documentElement.offsetWidth) - 200) + 'px';
|
||||
$('map').style.width = viewwidth;
|
||||
$('report').style.width = viewwidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
$('map').style.width = ((document.documentElement.clientWidth > 0?document.documentElement.clientWidth:document.documentElement.offsetWidth) - 0) + 'px';
|
||||
$('map').style.left = '0px';
|
||||
}
|
||||
|
||||
if ($('map')) $('map').style.height = ((document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38) + 'px';
|
||||
if ($('searchresults')) $('searchresults').style.height = ((document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38) + 'px';
|
||||
if ($('report')) $('report').style.height = ((document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38) + 'px';
|
||||
}
|
||||
window.onresize = handleResize;
|
||||
|
||||
function panToLatLon(lat,lon) {
|
||||
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
||||
map.panTo(lonLat, <?php echo $iZoom ?>);
|
||||
}
|
||||
|
||||
function panToLatLonZoom(lat, lon, zoom) {
|
||||
var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
||||
if (zoom != map.getZoom())
|
||||
map.setCenter(lonLat, zoom);
|
||||
else
|
||||
map.panTo(lonLat, 10);
|
||||
}
|
||||
|
||||
function panToLatLonBoundingBox(lat,lon,minlat,maxlat,minlon,maxlon,wkt) {
|
||||
vectorLayer.destroyFeatures();
|
||||
var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
|
||||
var proj_map = map.getProjectionObject();
|
||||
map.zoomToExtent(new OpenLayers.Bounds(minlon,minlat,maxlon,maxlat).transform(proj_EPSG4326, proj_map));
|
||||
var lonLat = new OpenLayers.LonLat(lon, lat).transform(proj_EPSG4326, proj_map);
|
||||
map.panTo(lonLat, <?php echo $iZoom ?>);
|
||||
|
||||
if (wkt)
|
||||
{
|
||||
var freader = new OpenLayers.Format.WKT({
|
||||
'internalProjection': proj_map,
|
||||
'externalProjection': proj_EPSG4326
|
||||
});
|
||||
|
||||
var feature = freader.read(wkt);
|
||||
if (feature)
|
||||
{
|
||||
feature.style = {
|
||||
strokeColor: "#75ADFF",
|
||||
fillColor: "#F0F7FF",
|
||||
strokeWidth: 2,
|
||||
strokeOpacity: 0.75,
|
||||
fillOpacity: 0.75,
|
||||
pointRadius: 100
|
||||
};
|
||||
vectorLayer.addFeatures([feature]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function round(v,n)
|
||||
{
|
||||
n = Math.pow(10,n);
|
||||
return Math.round(v*n)/n;
|
||||
}
|
||||
function floor(v,n)
|
||||
{
|
||||
n = Math.pow(10,n);
|
||||
return Math.floor(v*n)/n;
|
||||
}
|
||||
function ceil(v,n)
|
||||
{
|
||||
n = Math.pow(10,n);
|
||||
return Math.ceil(v*n)/n;
|
||||
}
|
||||
|
||||
function mapEventMove() {
|
||||
var proj = new OpenLayers.Projection("EPSG:4326");
|
||||
var bounds = map.getExtent();
|
||||
bounds = bounds.transform(map.getProjectionObject(), proj);
|
||||
$('viewbox').value = floor(bounds.left,2)+','+ceil(bounds.top,2)+','+ceil(bounds.right,2)+','+floor(bounds.bottom,2);
|
||||
}
|
||||
|
||||
function init() {
|
||||
handleResize();
|
||||
map = new OpenLayers.Map ("map", {
|
||||
controls:[
|
||||
new OpenLayers.Control.Navigation(),
|
||||
new OpenLayers.Control.PanZoomBar(),
|
||||
new OpenLayers.Control.MousePosition(),
|
||||
new OpenLayers.Control.Attribution()],
|
||||
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
|
||||
maxResolution: 156543.0399,
|
||||
numZoomLevels: 19,
|
||||
units: 'm',
|
||||
projection: new OpenLayers.Projection("EPSG:900913"),
|
||||
displayProjection: new OpenLayers.Projection("EPSG:4326"),
|
||||
eventListeners: {
|
||||
"moveend": mapEventMove
|
||||
}
|
||||
} );
|
||||
map.addLayer(new OpenLayers.Layer.OSM.<?php echo CONST_Tile_Default;?>("Default"));
|
||||
|
||||
var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
|
||||
layer_style.fillOpacity = 0.2;
|
||||
layer_style.graphicOpacity = 1;
|
||||
vectorLayer = new OpenLayers.Layer.Vector("Points", {style: layer_style});
|
||||
map.addLayer(vectorLayer);
|
||||
|
||||
// var lonLat = new OpenLayers.LonLat(<?php echo $fLon ?>, <?php echo $fLat ?>).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
|
||||
// map.setCenter (lonLat, <?php echo $iZoom ?>);
|
||||
}
|
||||
|
||||
function setfocus(field_id) {
|
||||
$(field_id).focus()
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="setfocus('q');">
|
||||
<body id="search-page">
|
||||
|
||||
<div id="seachheaderfade1"></div><div id="seachheaderfade2"></div><div id="seachheaderfade3"></div><div id="seachheaderfade4"></div>
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
|
||||
|
||||
<div id="seachheader">
|
||||
<form accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>search.php" method="get">
|
||||
<table border="0" width="100%" summary="header">
|
||||
<tr>
|
||||
<td valign="middle" style="width:30px;"><img alt="logo" src="images/logo.gif" /></td>
|
||||
<td valign="middle" style="width:400px;"><input id="q" name="q" value="<?php echo htmlspecialchars($sQuery);
|
||||
?>" style="width:270px;" /><input type="text" id="viewbox" style="width:120px;" name="viewbox" /></td>
|
||||
<td style="width:80px;"><input type="submit" value="Search"/></td>
|
||||
<?php if (CONST_Search_AreaPolygons) { ?> <td style="width:100px;"><input type="checkbox" value="1" name="polygon" <?php if ($bAsText) echo "checked='checked'"; ?>/> Highlight</td>
|
||||
<td style="text-align:right;">Data: <?php echo $sDataDate; ?></td>
|
||||
<td style="text-align:right;">
|
||||
<a href="http://wiki.openstreetmap.org/wiki/Nominatim" target="_blank">Documentation</a> | <a href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ"
|
||||
target="_blank">FAQ</a></td>
|
||||
|
||||
<?php } ?> <td style="text-align:right;"><?php if ($sQuery) { ?><input type="button" value="Report Problem With Results" onclick="$('report').style.visibility=($('report').style.visibility=='hidden'?'visible':'hidden')"/><?php } ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ($sQuery)
|
||||
{
|
||||
?>
|
||||
<div id="searchresultsfade1"></div><div id="searchresultsfade2"></div><div id="searchresultsfade3"></div><div id="searchresultsfade4"></div>
|
||||
<div id="searchresults">
|
||||
<?php
|
||||
if ($sSuggestionURL)
|
||||
{
|
||||
echo '<div class="more"><b>Suggest: </b><a href="'.$sSuggestionURL.'"><b>'.$sSuggestion.'</b></a></div>';
|
||||
}
|
||||
foreach($aSearchResults as $iResNum => $aResult)
|
||||
{
|
||||
if ($aResult['aBoundingBox'])
|
||||
{
|
||||
echo '<div class="result" onClick=\'panToLatLonBoundingBox('.$aResult['lat'].', '.$aResult['lon'];
|
||||
echo ', '.$aResult['aBoundingBox'][0];
|
||||
echo ', '.$aResult['aBoundingBox'][1];
|
||||
echo ', '.$aResult['aBoundingBox'][2];
|
||||
echo ', '.$aResult['aBoundingBox'][3];
|
||||
if (isset($aResult['astext'])) echo ', "'.$aResult['astext'].'"';
|
||||
echo ");'>\n";
|
||||
}
|
||||
elseif (isset($aResult['zoom']))
|
||||
{
|
||||
echo '<div class="result" onClick="panToLatLonZoom('.$aResult['lat'].', '.$aResult['lon'].', '.$aResult['zoom'].');">';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<div class="result" onClick="panToLatLon('.$aResult['lat'].', '.$aResult['lon'].');">';
|
||||
}
|
||||
|
||||
echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
|
||||
echo ' <span class="name">'.$aResult['name'].'</span>';
|
||||
echo ' <span class="latlon">'.round($aResult['lat'],3).','.round($aResult['lon'],3).'</span>';
|
||||
echo ' <span class="place_id">'.$aResult['place_id'].'</span>';
|
||||
if (isset($aResult['label']))
|
||||
echo ' <span class="type">('.$aResult['label'].')</span>';
|
||||
else
|
||||
echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
|
||||
echo ' <span class="details">(<a href="details.php?place_id='.$aResult['place_id'].'">details</a>)</span>';
|
||||
echo '</div>';
|
||||
}
|
||||
if (sizeof($aSearchResults))
|
||||
{
|
||||
if ($sMoreURL)
|
||||
{
|
||||
echo '<div class="more"><a href="'.htmlentities($sMoreURL).'">Search for more results</a></div>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<div class="noresults">No search results found</div>';
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="disclaimer">Addresses and postcodes are approximate
|
||||
<input type="button" value="Report Problem" onclick="$('report').style.visibility=($('report').style.visibility=='hidden'?'visible':'hidden')"/>
|
||||
<form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>search.php">
|
||||
<div class="form-group">
|
||||
<input id="q" name="q" type="text" class="form-control input-sm" placeholder="Search" value="<?php echo htmlspecialchars($sQuery); ?>" >
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div class="form-group search-button-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Search</button>
|
||||
<?php if (CONST_Search_AreaPolygons) { ?>
|
||||
<!-- <input type="checkbox" value="1" name="polygon" <?php if ($bAsText) echo "checked='checked'"; ?>/> Highlight -->
|
||||
<input type="hidden" value="1" name="polygon" />
|
||||
<?php } ?>
|
||||
<input type="hidden" name="viewbox" value="<?php echo $sViewBox; ?>" />
|
||||
<div class="checkbox-inline">
|
||||
<label>
|
||||
<input type="checkbox" id="use_viewbox" <?php if ($sViewBox) echo "checked='checked'"; ?>>
|
||||
apply viewbox
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-type-link">
|
||||
<a href="<?php echo CONST_Website_BaseURL; ?>reverse.php?format=html">reverse search</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="map"></div>
|
||||
<div id="report" style="visibility:hidden;"><div style="width:600px;margin:auto;margin-top:60px;">
|
||||
<h2>Report a problem</h2>
|
||||
<p>Before reporting problems please read the <a href="http://wiki.openstreetmap.org/wiki/Nominatim">user documentation</a> and <a
|
||||
href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ">FAQ</a>. If your problem relates to the address of a particular search result please use the 'details' link
|
||||
to check how the address was generated before reporting a problem.</p>
|
||||
<p>Please use <a href="http://trac.openstreetmap.org/newticket?component=nominatim">trac.openstreetmap.org</a> to report problems
|
||||
making sure to set
|
||||
the component to 'nominatim'. You can search for existing bug reports <a href="http://trac.openstreetmap.org/query?status=new&status=assigned&status=reopened&component=nominatim&order=priority">here</a>.</p>
|
||||
<p>Please ensure that you include a full description of the problem, including the search query that you used, the problem with the result and, if
|
||||
the problem relates to missing data, the osm id of the item that is missing. Problems that contain enough detail are likely to get looked at before ones that
|
||||
require significant research!</p>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<?php if ($sQuery) { ?>
|
||||
|
||||
<div id="searchresults" class="sidebar">
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach($aSearchResults as $iResNum => $aResult)
|
||||
{
|
||||
|
||||
echo '<div class="result" data-position=' . $i . '>';
|
||||
|
||||
echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
|
||||
echo ' <span class="name">'.htmlspecialchars($aResult['name']).'</span>';
|
||||
// echo ' <span class="latlon">'.round($aResult['lat'],3).','.round($aResult['lon'],3).'</span>';
|
||||
// echo ' <span class="place_id">'.$aResult['place_id'].'</span>';
|
||||
if (isset($aResult['label']))
|
||||
echo ' <span class="type">('.$aResult['label'].')</span>';
|
||||
else if ($aResult['type'] == 'yes')
|
||||
echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
|
||||
else
|
||||
echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
|
||||
echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
|
||||
echo '</div>';
|
||||
$i = $i+1;
|
||||
}
|
||||
if (sizeof($aSearchResults) && $sMoreURL)
|
||||
{
|
||||
echo '<div class="more"><a class="btn btn-primary" href="'.htmlentities($sMoreURL).'">Search for more results</a></div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<div class="noresults">No search results found</div>';
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<p>Please use this form to report problems with the search results. Of particular interest are items missing, but please also use this form to
|
||||
report any other problems.</p>
|
||||
<p>If your problem relates to the address of a particular search result please use the 'details' link to check how the address was generated before
|
||||
reporting a problem.</p>
|
||||
<p>If you are reporting a missing result please (if possible) include the OSM ID of the item you where expecting (i.e. node 422162)</p>
|
||||
<form method="post">
|
||||
<table>
|
||||
<tr><th>Your Query:</th><td><input type="hidden" name="report:query" value="<?php echo htmlspecialchars($sQuery); ?>" style="width:500px;"><?php echo htmlspecialchars($sQuery); ?></td></tr>
|
||||
<tr><th>Your Email Address(opt):</th><td><input type="text" name="report:email" value="" style="width:500px;"></td></tr>
|
||||
<tr><th>Description of Problem:</th><td><textarea name="report:description" style="width:500px;height:200px;"></textarea></td></tr>
|
||||
<tr><td colspan="2" class="button"><input type="button" value="Cancel" onclick="$('report').style.visibility='hidden'"><input type="submit" value="Report"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<h2>Known Problems</h2>
|
||||
<ul>
|
||||
<li>Countries where missed out of the index</li>
|
||||
<li>Area Polygons relate to the search area - not the address area which would make more sense</li>
|
||||
</ul>
|
||||
-->
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
|
||||
<div id="intro" class="sidebar">
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/introduction.php'); ?>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<div id="map-wrapper">
|
||||
<div id="map-position"></div>
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
init();
|
||||
<?php
|
||||
foreach($aSearchResults as $iResNum => $aResult)
|
||||
{
|
||||
if ($aResult['aBoundingBox'])
|
||||
{
|
||||
echo 'panToLatLonBoundingBox('.$aResult['lat'].', '.$aResult['lon'];
|
||||
echo ', '.$aResult['aBoundingBox'][0];
|
||||
echo ', '.$aResult['aBoundingBox'][1];
|
||||
echo ', '.$aResult['aBoundingBox'][2];
|
||||
echo ', '.$aResult['aBoundingBox'][3];
|
||||
if (isset($aResult['astext'])) echo ", '".$aResult['astext']."'";
|
||||
echo ');'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'panToLatLonZoom('.$fLat.', '.$fLon.', '.$iZoom.');'."\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!sizeof($aSearchResults))
|
||||
{
|
||||
echo 'panToLatLonZoom('.$fLat.', '.$fLon.', '.$iZoom.');'."\n";
|
||||
}
|
||||
?>
|
||||
</script>
|
||||
</body>
|
||||
<?php
|
||||
|
||||
$aNominatimMapInit = array(
|
||||
'zoom' => $iZoom,
|
||||
'lat' => $fLat,
|
||||
'lon' => $fLon,
|
||||
'tile_url' => $sTileURL,
|
||||
'tile_attribution' => $sTileAttribution
|
||||
);
|
||||
echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
|
||||
|
||||
echo 'var nominatim_results = ' . json_encode($aSearchResults, JSON_PRETTY_PRINT) . ';';
|
||||
?>
|
||||
</script>
|
||||
<?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -74,6 +74,9 @@
|
||||
$aPlace['geokml'] = $aPointDetails['askml'];
|
||||
}
|
||||
|
||||
if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
|
||||
if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
|
||||
|
||||
$aFilteredPlaces[] = $aPlace;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,10 @@
|
||||
$aPlace['geokml'] = $aPointDetails['askml'];
|
||||
}
|
||||
|
||||
if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
|
||||
if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
|
||||
|
||||
$aFilteredPlaces[] = $aPlace;
|
||||
}
|
||||
|
||||
javascript_renderData($aFilteredPlaces, array('geojson'));
|
||||
javascript_renderData($aFilteredPlaces);
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
echo "?xml version=\"1.0\" encoding=\"UTF-8\" ?";
|
||||
echo ">\n";
|
||||
|
||||
echo "<searchresults";
|
||||
echo "<";
|
||||
echo (isset($sXmlRootTag)?$sXmlRootTag:'searchresults');
|
||||
echo " timestamp='".date(DATE_RFC822)."'";
|
||||
echo " attribution='Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'";
|
||||
echo " querystring='".htmlspecialchars($sQuery, ENT_QUOTES)."'";
|
||||
@@ -87,20 +88,59 @@
|
||||
echo " icon='".htmlspecialchars($aResult['icon'], ENT_QUOTES)."'";
|
||||
}
|
||||
|
||||
if (isset($aResult['address']) || isset($aResult['askml']))
|
||||
{
|
||||
echo ">";
|
||||
}
|
||||
$bHasDelim = false;
|
||||
|
||||
if (isset($aResult['askml']))
|
||||
{
|
||||
if (!$bHasDelim)
|
||||
{
|
||||
$bHasDelim = true;
|
||||
echo ">";
|
||||
}
|
||||
echo "\n<geokml>";
|
||||
echo $aResult['askml'];
|
||||
echo "</geokml>";
|
||||
}
|
||||
|
||||
if (isset($aResult['sExtraTags']))
|
||||
{
|
||||
if (!$bHasDelim)
|
||||
{
|
||||
$bHasDelim = true;
|
||||
echo ">";
|
||||
}
|
||||
echo "\n<extratags>";
|
||||
foreach ($aResult['sExtraTags'] as $sKey => $sValue)
|
||||
{
|
||||
echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
|
||||
}
|
||||
echo "</extratags>";
|
||||
}
|
||||
|
||||
if (isset($aResult['sNameDetails']))
|
||||
{
|
||||
if (!$bHasDelim)
|
||||
{
|
||||
$bHasDelim = true;
|
||||
echo ">";
|
||||
}
|
||||
echo "\n<namedetails>";
|
||||
foreach ($aResult['sNameDetails'] as $sKey => $sValue)
|
||||
{
|
||||
echo '<name desc="'.htmlspecialchars($sKey).'">';
|
||||
echo htmlspecialchars($sValue);
|
||||
echo "</name>";
|
||||
}
|
||||
echo "</namedetails>";
|
||||
}
|
||||
|
||||
if (isset($aResult['address']))
|
||||
{
|
||||
if (!$bHasDelim)
|
||||
{
|
||||
$bHasDelim = true;
|
||||
echo ">";
|
||||
}
|
||||
echo "\n";
|
||||
foreach($aResult['address'] as $sKey => $sValue)
|
||||
{
|
||||
@@ -111,7 +151,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($aResult['address']) || isset($aResult['askml']))
|
||||
if ($bHasDelim)
|
||||
{
|
||||
echo "</place>";
|
||||
}
|
||||
@@ -121,4 +161,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
echo "</searchresults>";
|
||||
echo "</" . (isset($sXmlRootTag)?$sXmlRootTag:'searchresults') . ">";
|
||||
|
||||
125
m4/ax_lib_postgresql_svr.m4
Normal file
125
m4/ax_lib_postgresql_svr.m4
Normal file
@@ -0,0 +1,125 @@
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_LIB_POSTGRESQL_SVR([MINIMUM-VERSION])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro provides tests of availability of PostgreSQL server library
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(POSTGRESQL_PGXS)
|
||||
# AC_SUBST(POSTGRESQL_SERVER_CFLAGS)
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Mateusz Loskot <mateusz@loskot.net>
|
||||
# Copyright (c) 2015 Sarah Hoffmann <lonia@denofr.de>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AX_LIB_POSTGRESQL_SVR],
|
||||
[
|
||||
AC_ARG_WITH([postgresql],
|
||||
AC_HELP_STRING([--with-postgresql-svr=@<:@ARG@:>@],
|
||||
[use PostgreSQL server library @<:@default=yes@:>@, optionally specify path to pg_config]
|
||||
),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_postgresql="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_postgresql="yes"
|
||||
else
|
||||
want_postgresql="yes"
|
||||
PG_CONFIG="$withval"
|
||||
fi
|
||||
],
|
||||
[want_postgresql="yes"]
|
||||
)
|
||||
|
||||
dnl
|
||||
dnl Check PostgreSQL server libraries
|
||||
dnl
|
||||
|
||||
if test "$want_postgresql" = "yes"; then
|
||||
|
||||
if test -z "$PG_CONFIG" -o test; then
|
||||
AC_PATH_PROG([PG_CONFIG], [pg_config], [])
|
||||
fi
|
||||
|
||||
if test ! -x "$PG_CONFIG"; then
|
||||
AC_MSG_ERROR([$PG_CONFIG does not exist or it is not an exectuable file])
|
||||
PG_CONFIG="no"
|
||||
found_postgresql="no"
|
||||
fi
|
||||
|
||||
if test "$PG_CONFIG" != "no"; then
|
||||
AC_MSG_CHECKING([for PostgreSQL server libraries])
|
||||
|
||||
POSTGRESQL_SERVER_CFLAGS="-I`$PG_CONFIG --includedir-server`"
|
||||
|
||||
POSTGRESQL_VERSION=`$PG_CONFIG --version | sed -e 's#PostgreSQL ##'`
|
||||
|
||||
POSTGRESQL_PGXS=`$PG_CONFIG --pgxs`
|
||||
if test -f "$POSTGRESQL_PGXS"
|
||||
then
|
||||
found_postgresql="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
else
|
||||
found_postgresql="no"
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if required version of PostgreSQL is available
|
||||
dnl
|
||||
|
||||
|
||||
postgresql_version_req=ifelse([$1], [], [], [$1])
|
||||
|
||||
if test "$found_postgresql" = "yes" -a -n "$postgresql_version_req"; then
|
||||
|
||||
AC_MSG_CHECKING([if PostgreSQL version is >= $postgresql_version_req])
|
||||
|
||||
dnl Decompose required version string of PostgreSQL
|
||||
dnl and calculate its number representation
|
||||
postgresql_version_req_major=`expr $postgresql_version_req : '\([[0-9]]*\)'`
|
||||
postgresql_version_req_minor=`expr $postgresql_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
postgresql_version_req_micro=`expr $postgresql_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$postgresql_version_req_micro" = "x"; then
|
||||
postgresql_version_req_micro="0"
|
||||
fi
|
||||
|
||||
postgresql_version_req_number=`expr $postgresql_version_req_major \* 1000000 \
|
||||
\+ $postgresql_version_req_minor \* 1000 \
|
||||
\+ $postgresql_version_req_micro`
|
||||
|
||||
dnl Decompose version string of installed PostgreSQL
|
||||
dnl and calculate its number representation
|
||||
postgresql_version_major=`expr $POSTGRESQL_VERSION : '\([[0-9]]*\)'`
|
||||
postgresql_version_minor=`expr $POSTGRESQL_VERSION : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
postgresql_version_micro=`expr $POSTGRESQL_VERSION : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$postgresql_version_micro" = "x"; then
|
||||
postgresql_version_micro="0"
|
||||
fi
|
||||
|
||||
postgresql_version_number=`expr $postgresql_version_major \* 1000000 \
|
||||
\+ $postgresql_version_minor \* 1000 \
|
||||
\+ $postgresql_version_micro`
|
||||
|
||||
postgresql_version_check=`expr $postgresql_version_number \>\= $postgresql_version_req_number`
|
||||
if test "$postgresql_version_check" = "1"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([POSTGRESQL_PGXS])
|
||||
AC_SUBST([POSTGRESQL_SERVER_CFLAGS])
|
||||
])
|
||||
|
||||
150
m4/ax_lib_xml2.m4
Normal file
150
m4/ax_lib_xml2.m4
Normal file
@@ -0,0 +1,150 @@
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_LIB_XML2([MINIMUM-VERSION])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro provides tests of availability of xml2 'libxml2' library
|
||||
# of particular version or newer.
|
||||
#
|
||||
# AX_LIB_LIBXML2 macro takes only one argument which is optional. If
|
||||
# there is no required version passed, then macro does not run version
|
||||
# test.
|
||||
#
|
||||
# The --with-libxml2 option takes one of three possible values:
|
||||
#
|
||||
# no - do not check for xml2 library
|
||||
#
|
||||
# yes - do check for xml2 library in standard locations (xml2-config
|
||||
# should be in the PATH)
|
||||
#
|
||||
# path - complete path to xml2-config utility, use this option if xml2-config
|
||||
# can't be found in the PATH
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(XML2_CFLAGS)
|
||||
# AC_SUBST(XML2_LDFLAGS)
|
||||
# AC_SUBST(XML2_VERSION)
|
||||
#
|
||||
# And sets:
|
||||
#
|
||||
# HAVE_XML2
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Hartmut Holzgraefe <hartmut@php.net>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AX_LIB_XML2],
|
||||
[
|
||||
AC_ARG_WITH([libxml2],
|
||||
AC_HELP_STRING([--with-libxml2=@<:@ARG@:>@],
|
||||
[use libxml2 library @<:@default=yes@:>@, optionally specify path to xml2-config]
|
||||
),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_libxml2="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_libxml2="yes"
|
||||
else
|
||||
want_libxml2="yes"
|
||||
XML2_CONFIG="$withval"
|
||||
fi
|
||||
],
|
||||
[want_libxml2="yes"]
|
||||
)
|
||||
|
||||
XML2_CFLAGS=""
|
||||
XML2_LDFLAGS=""
|
||||
XML2_VERSION=""
|
||||
|
||||
dnl
|
||||
dnl Check xml2 libraries (libxml2)
|
||||
dnl
|
||||
|
||||
if test "$want_libxml2" = "yes"; then
|
||||
|
||||
if test -z "$XML2_CONFIG" -o test; then
|
||||
AC_PATH_PROG([XML2_CONFIG], [xml2-config], [])
|
||||
fi
|
||||
|
||||
if test ! -x "$XML2_CONFIG"; then
|
||||
AC_MSG_ERROR([$XML2_CONFIG does not exist or it is not an exectuable file])
|
||||
XML2_CONFIG="no"
|
||||
found_libxml2="no"
|
||||
fi
|
||||
|
||||
if test "$XML2_CONFIG" != "no"; then
|
||||
AC_MSG_CHECKING([for xml2 libraries])
|
||||
|
||||
XML2_CFLAGS="`$XML2_CONFIG --cflags`"
|
||||
XML2_LDFLAGS="`$XML2_CONFIG --libs`"
|
||||
|
||||
XML2_VERSION=`$XML2_CONFIG --version`
|
||||
|
||||
AC_DEFINE([HAVE_XML2], [1],
|
||||
[Define to 1 if xml2 libraries are available])
|
||||
|
||||
found_libxml2="yes"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
found_libxml2="no"
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check if required version of xml2 is available
|
||||
dnl
|
||||
|
||||
|
||||
libxml2_version_req=ifelse([$1], [], [], [$1])
|
||||
|
||||
|
||||
if test "$found_libxml2" = "yes" -a -n "$libxml2_version_req"; then
|
||||
|
||||
AC_MSG_CHECKING([if libxml2 version is >= $libxml2_version_req])
|
||||
|
||||
dnl Decompose required version string of libxml2
|
||||
dnl and calculate its number representation
|
||||
libxml2_version_req_major=`expr $libxml2_version_req : '\([[0-9]]*\)'`
|
||||
libxml2_version_req_minor=`expr $libxml2_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
libxml2_version_req_micro=`expr $libxml2_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$libxml2_version_req_micro" = "x"; then
|
||||
libxml2_version_req_micro="0"
|
||||
fi
|
||||
|
||||
libxml2_version_req_number=`expr $libxml2_version_req_major \* 1000000 \
|
||||
\+ $libxml2_version_req_minor \* 1000 \
|
||||
\+ $libxml2_version_req_micro`
|
||||
|
||||
dnl Decompose version string of installed PostgreSQL
|
||||
dnl and calculate its number representation
|
||||
libxml2_version_major=`expr $XML2_VERSION : '\([[0-9]]*\)'`
|
||||
libxml2_version_minor=`expr $XML2_VERSION : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
libxml2_version_micro=`expr $XML2_VERSION : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$libxml2_version_micro" = "x"; then
|
||||
libxml2_version_micro="0"
|
||||
fi
|
||||
|
||||
libxml2_version_number=`expr $libxml2_version_major \* 1000000 \
|
||||
\+ $libxml2_version_minor \* 1000 \
|
||||
\+ $libxml2_version_micro`
|
||||
|
||||
libxml2_version_check=`expr $libxml2_version_number \>\= $libxml2_version_req_number`
|
||||
if test "$libxml2_version_check" = "1"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST([XML2_VERSION])
|
||||
AC_SUBST([XML2_CFLAGS])
|
||||
AC_SUBST([XML2_LDFLAGS])
|
||||
])
|
||||
|
||||
@@ -2,8 +2,8 @@ bin_PROGRAMS = nominatim
|
||||
|
||||
nominatim_SOURCES = export.c geometry.cpp import.c index.c input.c nominatim.c postgresql.c sprompt.c
|
||||
|
||||
AM_CFLAGS = @PTHREAD_CFLAGS@ @POSTGRESQL_CFLAGS@ @XML_CPPFLAGS@ @BZIP2_CFLAGS@ @GEOS_CFLAGS@ @PROJ_CFLAGS@ -DVERSION='"@PACKAGE_VERSION@"'
|
||||
AM_CPPFLAGS = @PTHREAD_CFLAGS@ @POSTGRESQL_CFLAGS@ @XML_CPPFLAGS@ @BZIP2_CFLAGS@ @GEOS_CFLAGS@ @PROJ_CFLAGS@
|
||||
AM_CFLAGS = @PTHREAD_CFLAGS@ @POSTGRESQL_CPPFLAGS@ @XML_CPPFLAGS@ @BZIP2_CFLAGS@ @GEOS_CFLAGS@ @PROJ_CFLAGS@ -DVERSION='"@PACKAGE_VERSION@"'
|
||||
AM_CPPFLAGS = @PTHREAD_CFLAGS@ @POSTGRESQL_CPPFLAGS@ @XML_CPPFLAGS@ @BZIP2_CFLAGS@ @GEOS_CFLAGS@ @PROJ_CFLAGS@
|
||||
|
||||
nominatim_LDADD = @PTHREAD_CFLAGS@ @POSTGRESQL_LDFLAGS@ @POSTGRESQL_LIBS@ @XML_LIBS@ @BZIP2_LDFLAGS@ @BZIP2_LIBS@ @GEOS_LDFLAGS@ @GEOS_LIBS@ @PROJ_LDFLAGS@ @PROJ_LIBS@ -lz
|
||||
|
||||
|
||||
Submodule osm2pgsql updated: 7d780c931c...8179cdb67e
@@ -5,22 +5,48 @@
|
||||
// General settings
|
||||
@define('CONST_Debug', false);
|
||||
@define('CONST_Database_DSN', 'pgsql://@/nominatim'); // <driver>://<username>:<password>@<host>:<port>/<database>
|
||||
@define('CONST_Database_Web_User', 'www-data');
|
||||
@define('CONST_Max_Word_Frequency', '50000');
|
||||
@define('CONST_Limit_Reindexing', true);
|
||||
|
||||
// Proxy settings
|
||||
@define('CONST_HTTP_Proxy', false);
|
||||
@define('CONST_HTTP_Proxy_Host', 'proxy.mydomain.com');
|
||||
@define('CONST_HTTP_Proxy_Port', '3128');
|
||||
@define('CONST_HTTP_Proxy_Login', '');
|
||||
@define('CONST_HTTP_Proxy_Password', '');
|
||||
|
||||
// Software versions
|
||||
@define('CONST_Postgresql_Version', '9.1'); // values: 8.3, 8.4, 9.0, 9.1, 9.2
|
||||
@define('CONST_Postgis_Version', '1.5'); // values: 1.5, 2.0
|
||||
@define('CONST_Postgresql_Version', '9.3'); // values: 9.0, ... , 9.4
|
||||
@define('CONST_Postgis_Version', '2.1'); // values: 1.5, 2.0, 2.1
|
||||
|
||||
// Paths
|
||||
@define('CONST_Path_Postgresql_Contrib', '/usr/share/postgresql/'.CONST_Postgresql_Version.'/contrib');
|
||||
@define('CONST_Path_Postgresql_Postgis', CONST_Path_Postgresql_Contrib.'/postgis-'.CONST_Postgis_Version);
|
||||
@define('CONST_Osm2pgsql_Binary', CONST_BasePath.'/osm2pgsql/osm2pgsql');
|
||||
@define('CONST_Osmosis_Binary', '/usr/bin/osmosis');
|
||||
@define('CONST_Tiger_Data_Path', CONST_BasePath.'/data/tiger');
|
||||
|
||||
// osm2pgsql settings
|
||||
@define('CONST_Osm2pgsql_Flatnode_File', null);
|
||||
|
||||
// tablespace settings
|
||||
// osm2pgsql caching tables (aka slim mode tables) - update only
|
||||
@define('CONST_Tablespace_Osm2pgsql_Data', false);
|
||||
@define('CONST_Tablespace_Osm2pgsql_Index', false);
|
||||
// osm2pgsql output tables (aka main table) - update only
|
||||
@define('CONST_Tablespace_Place_Data', false);
|
||||
@define('CONST_Tablespace_Place_Index', false);
|
||||
// address computation tables - update only
|
||||
@define('CONST_Tablespace_Address_Data', false);
|
||||
@define('CONST_Tablespace_Address_Index', false);
|
||||
// search tables - needed for lookups
|
||||
@define('CONST_Tablespace_Search_Data', false);
|
||||
@define('CONST_Tablespace_Search_Index', false);
|
||||
// additional data, e.g. TIGER data, type searches - needed for lookups
|
||||
@define('CONST_Tablespace_Aux_Data', false);
|
||||
@define('CONST_Tablespace_Aux_Index', false);
|
||||
|
||||
// Replication settings
|
||||
@define('CONST_Replication_Url', 'http://planet.openstreetmap.org/replication/minute');
|
||||
@define('CONST_Replication_MaxInterval', '3600');
|
||||
@@ -65,6 +91,8 @@
|
||||
@define('CONST_Default_Lat', 20.0);
|
||||
@define('CONST_Default_Lon', 0.0);
|
||||
@define('CONST_Default_Zoom', 2);
|
||||
@define('CONST_Map_Tile_URL', 'http://{s}.tile.osm.org/{z}/{x}/{y}.png');
|
||||
@define('CONST_Map_Tile_Attribution', ''); // Set if tile source isn't osm.org
|
||||
|
||||
@define('CONST_Search_AreaPolygons_Enabled', true);
|
||||
@define('CONST_Search_AreaPolygons', true);
|
||||
@@ -72,7 +100,12 @@
|
||||
@define('CONST_Search_BatchMode', false);
|
||||
|
||||
@define('CONST_Search_TryDroppedAddressTerms', false);
|
||||
@define('CONST_Search_NameOnlySearchFrequencyThreshold', false);
|
||||
@define('CONST_Search_NameOnlySearchFrequencyThreshold', 500);
|
||||
// If set to true, then reverse order of queries will be tried by default.
|
||||
// When set to false only selected languages alloow reverse search.
|
||||
@define('CONST_Search_ReversePlanForAll', true);
|
||||
|
||||
@define('CONST_Places_Max_ID_count', 50);
|
||||
|
||||
// Set to zero to disable polygon output
|
||||
@define('CONST_PolygonOutput_MaximumTypes', 1);
|
||||
@@ -83,3 +116,5 @@
|
||||
@define('CONST_Log_File_Format', 'TODO'); // Currently hard coded
|
||||
@define('CONST_Log_File_SearchLog', '');
|
||||
@define('CONST_Log_File_ReverseLog', '');
|
||||
|
||||
|
||||
|
||||
1036
sql/functions.sql
1036
sql/functions.sql
File diff suppressed because it is too large
Load Diff
@@ -1,30 +1,30 @@
|
||||
-- Indices used only during search and update.
|
||||
-- These indices are created only after the indexing process is done.
|
||||
|
||||
CREATE INDEX idx_word_word_id on word USING BTREE (word_id);
|
||||
CREATE INDEX idx_word_word_id on word USING BTREE (word_id) {ts:search-index};
|
||||
|
||||
CREATE INDEX idx_search_name_nameaddress_vector ON search_name USING GIN (nameaddress_vector) WITH (fastupdate = off);
|
||||
CREATE INDEX idx_search_name_name_vector ON search_name USING GIN (name_vector) WITH (fastupdate = off);
|
||||
CREATE INDEX idx_search_name_centroid ON search_name USING GIST (centroid);
|
||||
CREATE INDEX idx_search_name_nameaddress_vector ON search_name USING GIN (nameaddress_vector) WITH (fastupdate = off) {ts:search-index};
|
||||
CREATE INDEX idx_search_name_name_vector ON search_name USING GIN (name_vector) WITH (fastupdate = off) {ts:search-index};
|
||||
CREATE INDEX idx_search_name_centroid ON search_name USING GIST (centroid) {ts:search-index};
|
||||
|
||||
CREATE INDEX idx_place_addressline_address_place_id on place_addressline USING BTREE (address_place_id);
|
||||
|
||||
CREATE INDEX idx_place_boundingbox_place_id on place_boundingbox USING BTREE (place_id);
|
||||
CREATE INDEX idx_place_boundingbox_outline ON place_boundingbox USING GIST (outline);
|
||||
CREATE INDEX idx_place_addressline_address_place_id on place_addressline USING BTREE (address_place_id) {ts:search-index};
|
||||
|
||||
DROP INDEX IF EXISTS idx_placex_rank_search;
|
||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search);
|
||||
CREATE INDEX idx_placex_rank_address ON placex USING BTREE (rank_address);
|
||||
CREATE INDEX idx_placex_pendingsector ON placex USING BTREE (rank_search,geometry_sector) where indexed_status > 0;
|
||||
CREATE INDEX idx_placex_parent_place_id ON placex USING BTREE (parent_place_id) where parent_place_id IS NOT NULL;
|
||||
CREATE INDEX idx_placex_interpolation ON placex USING BTREE (geometry_sector) where indexed_status > 0 and class='place' and type='houses';
|
||||
CREATE INDEX idx_placex_reverse_geometry ON placex USING gist (geometry) where rank_search != 28 and (name is not null or housenumber is not null) and class not in ('waterway','railway','tunnel','bridge');
|
||||
CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id);
|
||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search) {ts:search-index};
|
||||
CREATE INDEX idx_placex_rank_address ON placex USING BTREE (rank_address) {ts:search-index};
|
||||
CREATE INDEX idx_placex_pendingsector ON placex USING BTREE (rank_search,geometry_sector) {ts:address-index} where indexed_status > 0;
|
||||
CREATE INDEX idx_placex_parent_place_id ON placex USING BTREE (parent_place_id) {ts:search-index} where parent_place_id IS NOT NULL;
|
||||
CREATE INDEX idx_placex_reverse_geometry ON placex USING gist (geometry) {ts:search-index} where rank_search != 28 and (name is not null or housenumber is not null) and class not in ('waterway','railway','tunnel','bridge','man_made');
|
||||
CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id) {ts:address-index};
|
||||
|
||||
CREATE INDEX idx_search_name_country_centroid ON search_name_country USING GIST (centroid);
|
||||
CREATE INDEX idx_search_name_country_centroid ON search_name_country USING GIST (centroid) {ts:address-index};
|
||||
|
||||
-- start
|
||||
CREATE INDEX idx_location_property_-partition-_centroid ON location_property_-partition- USING GIST (centroid);
|
||||
CREATE INDEX idx_location_property_-partition-_centroid ON location_property_-partition- USING GIST (centroid) {ts:address-index};
|
||||
-- end
|
||||
|
||||
CREATE UNIQUE INDEX idx_place_osm_unique on place using btree(osm_id,osm_type,class,type);
|
||||
DROP INDEX IF EXISTS place_id_idx;
|
||||
CREATE UNIQUE INDEX idx_place_osm_unique on place using btree(osm_id,osm_type,class,type) {ts:address-index};
|
||||
|
||||
|
||||
CREATE INDEX idx_gb_postcode_postcode ON gb_postcode USING BTREE (postcode) {ts:search-index};
|
||||
|
||||
@@ -34,35 +34,35 @@ CREATE TABLE search_name_blank (
|
||||
SELECT AddGeometryColumn('search_name_blank', 'centroid', 4326, 'GEOMETRY', 2);
|
||||
|
||||
|
||||
CREATE TABLE location_area_country () INHERITS (location_area_large);
|
||||
CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry);
|
||||
CREATE TABLE location_area_country () INHERITS (location_area_large) {ts:address-data};
|
||||
CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry) {ts:address-index};
|
||||
|
||||
CREATE TABLE search_name_country () INHERITS (search_name_blank);
|
||||
CREATE INDEX idx_search_name_country_place_id ON search_name_country USING BTREE (place_id);
|
||||
CREATE INDEX idx_search_name_country_name_vector ON search_name_country USING GIN (name_vector) WITH (fastupdate = off);
|
||||
CREATE TABLE search_name_country () INHERITS (search_name_blank) {ts:address-data};
|
||||
CREATE INDEX idx_search_name_country_place_id ON search_name_country USING BTREE (place_id) {ts:address-index};
|
||||
CREATE INDEX idx_search_name_country_name_vector ON search_name_country USING GIN (name_vector) WITH (fastupdate = off) {ts:address-index};
|
||||
|
||||
-- start
|
||||
CREATE TABLE location_area_large_-partition- () INHERITS (location_area_large);
|
||||
CREATE INDEX idx_location_area_large_-partition-_place_id ON location_area_large_-partition- USING BTREE (place_id);
|
||||
CREATE INDEX idx_location_area_large_-partition-_geometry ON location_area_large_-partition- USING GIST (geometry);
|
||||
CREATE TABLE location_area_large_-partition- () INHERITS (location_area_large) {ts:address-data};
|
||||
CREATE INDEX idx_location_area_large_-partition-_place_id ON location_area_large_-partition- USING BTREE (place_id) {ts:address-index};
|
||||
CREATE INDEX idx_location_area_large_-partition-_geometry ON location_area_large_-partition- USING GIST (geometry) {ts:address-index};
|
||||
|
||||
CREATE TABLE search_name_-partition- () INHERITS (search_name_blank);
|
||||
CREATE INDEX idx_search_name_-partition-_place_id ON search_name_-partition- USING BTREE (place_id);
|
||||
CREATE INDEX idx_search_name_-partition-_centroid ON search_name_-partition- USING GIST (centroid);
|
||||
CREATE INDEX idx_search_name_-partition-_name_vector ON search_name_-partition- USING GIN (name_vector) WITH (fastupdate = off);
|
||||
CREATE TABLE search_name_-partition- () INHERITS (search_name_blank) {ts:address-data};
|
||||
CREATE INDEX idx_search_name_-partition-_place_id ON search_name_-partition- USING BTREE (place_id) {ts:address-index};
|
||||
CREATE INDEX idx_search_name_-partition-_centroid ON search_name_-partition- USING GIST (centroid) {ts:address-index};
|
||||
CREATE INDEX idx_search_name_-partition-_name_vector ON search_name_-partition- USING GIN (name_vector) WITH (fastupdate = off) {ts:address-index};
|
||||
|
||||
CREATE TABLE location_property_-partition- () INHERITS (location_property);
|
||||
CREATE INDEX idx_location_property_-partition-_place_id ON location_property_-partition- USING BTREE (place_id);
|
||||
CREATE INDEX idx_location_property_-partition-_parent_place_id ON location_property_-partition- USING BTREE (parent_place_id);
|
||||
CREATE INDEX idx_location_property_-partition-_housenumber_parent_place_id ON location_property_-partition- USING BTREE (parent_place_id, housenumber);
|
||||
CREATE TABLE location_property_-partition- () INHERITS (location_property) {ts:aux-data};
|
||||
CREATE INDEX idx_location_property_-partition-_place_id ON location_property_-partition- USING BTREE (place_id) {ts:aux-index};
|
||||
CREATE INDEX idx_location_property_-partition-_parent_place_id ON location_property_-partition- USING BTREE (parent_place_id) {ts:aux-index};
|
||||
CREATE INDEX idx_location_property_-partition-_housenumber_parent_place_id ON location_property_-partition- USING BTREE (parent_place_id, housenumber) {ts:aux-index};
|
||||
|
||||
CREATE TABLE location_road_-partition- (
|
||||
partition integer,
|
||||
place_id BIGINT,
|
||||
country_code VARCHAR(2)
|
||||
);
|
||||
) {ts:address-data};
|
||||
SELECT AddGeometryColumn('location_road_-partition-', 'geometry', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_location_road_-partition-_geometry ON location_road_-partition- USING GIST (geometry);
|
||||
CREATE INDEX idx_location_road_-partition-_place_id ON location_road_-partition- USING BTREE (place_id);
|
||||
CREATE INDEX idx_location_road_-partition-_geometry ON location_road_-partition- USING GIST (geometry) {ts:address-index};
|
||||
CREATE INDEX idx_location_road_-partition-_place_id ON location_road_-partition- USING BTREE (place_id) {ts:address-index};
|
||||
|
||||
-- end
|
||||
|
||||
14
sql/postgis_15_aux.sql
Normal file
14
sql/postgis_15_aux.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- Splits the line at the given point and returns the two parts
|
||||
-- in a multilinestring.
|
||||
CREATE OR REPLACE FUNCTION split_line_on_node(line GEOMETRY, point GEOMETRY)
|
||||
RETURNS GEOMETRY
|
||||
AS $$
|
||||
DECLARE
|
||||
frac FLOAT;
|
||||
BEGIN
|
||||
frac := ST_Line_Locate_Point(line, point);
|
||||
RETURN ST_Collect(ST_Line_Substring(line, 0, frac),
|
||||
ST_Line_Substring(line, frac, 1));
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
10
sql/postgis_20_aux.sql
Normal file
10
sql/postgis_20_aux.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- Splits the line at the given point and returns the two parts
|
||||
-- in a multilinestring.
|
||||
CREATE OR REPLACE FUNCTION split_line_on_node(line GEOMETRY, point GEOMETRY)
|
||||
RETURNS GEOMETRY
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN ST_Split(ST_Snap(line, point, 0.0005), point);
|
||||
END;
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
145
sql/tables.sql
145
sql/tables.sql
@@ -1,10 +1,10 @@
|
||||
drop table import_status;
|
||||
drop table if exists import_status;
|
||||
CREATE TABLE import_status (
|
||||
lastimportdate timestamp NOT NULL
|
||||
);
|
||||
GRANT SELECT ON import_status TO "www-data" ;
|
||||
GRANT SELECT ON import_status TO "{www-user}" ;
|
||||
|
||||
drop table import_osmosis_log;
|
||||
drop table if exists import_osmosis_log;
|
||||
CREATE TABLE import_osmosis_log (
|
||||
batchend timestamp,
|
||||
batchsize integer,
|
||||
@@ -13,7 +13,7 @@ CREATE TABLE import_osmosis_log (
|
||||
event text
|
||||
);
|
||||
|
||||
drop table import_npi_log;
|
||||
drop table if exists import_npi_log;
|
||||
CREATE TABLE import_npi_log (
|
||||
npiid integer,
|
||||
batchend timestamp,
|
||||
@@ -32,9 +32,9 @@ CREATE TABLE query_log (
|
||||
results integer
|
||||
);
|
||||
CREATE INDEX idx_query_log ON query_log USING BTREE (starttime);
|
||||
GRANT SELECT ON query_log TO "www-data" ;
|
||||
GRANT INSERT ON query_log TO "www-data" ;
|
||||
GRANT UPDATE ON query_log TO "www-data" ;
|
||||
GRANT SELECT ON query_log TO "{www-user}" ;
|
||||
GRANT INSERT ON query_log TO "{www-user}" ;
|
||||
GRANT UPDATE ON query_log TO "{www-user}" ;
|
||||
|
||||
CREATE TABLE new_query_log (
|
||||
type text,
|
||||
@@ -49,23 +49,16 @@ CREATE TABLE new_query_log (
|
||||
secret text
|
||||
);
|
||||
CREATE INDEX idx_new_query_log_starttime ON new_query_log USING BTREE (starttime);
|
||||
GRANT INSERT ON new_query_log TO "www-data" ;
|
||||
GRANT UPDATE ON new_query_log TO "www-data" ;
|
||||
GRANT SELECT ON new_query_log TO "www-data" ;
|
||||
GRANT INSERT ON new_query_log TO "{www-user}" ;
|
||||
GRANT UPDATE ON new_query_log TO "{www-user}" ;
|
||||
GRANT SELECT ON new_query_log TO "{www-user}" ;
|
||||
|
||||
GRANT SELECT ON TABLE country_name TO "{www-user}";
|
||||
GRANT SELECT ON TABLE gb_postcode TO "{www-user}";
|
||||
|
||||
create view vw_search_query_log as SELECT substr(query, 1, 50) AS query, starttime, endtime - starttime AS duration, substr(useragent, 1, 20) as
|
||||
useragent, language, results, ipaddress FROM new_query_log WHERE type = 'search' ORDER BY starttime DESC;
|
||||
|
||||
--drop table IF EXISTS report_log;
|
||||
CREATE TABLE report_log (
|
||||
starttime timestamp,
|
||||
ipaddress text,
|
||||
query text,
|
||||
description text,
|
||||
email text
|
||||
);
|
||||
GRANT INSERT ON report_log TO "www-data" ;
|
||||
|
||||
drop table IF EXISTS word;
|
||||
CREATE TABLE word (
|
||||
word_id INTEGER,
|
||||
@@ -76,17 +69,17 @@ CREATE TABLE word (
|
||||
country_code varchar(2),
|
||||
search_name_count INTEGER,
|
||||
operator TEXT
|
||||
);
|
||||
CREATE INDEX idx_word_word_token on word USING BTREE (word_token);
|
||||
GRANT SELECT ON word TO "www-data" ;
|
||||
DROP SEQUENCE seq_word;
|
||||
) {ts:search-data};
|
||||
CREATE INDEX idx_word_word_token on word USING BTREE (word_token) {ts:search-index};
|
||||
GRANT SELECT ON word TO "{www-user}" ;
|
||||
DROP SEQUENCE IF EXISTS seq_word;
|
||||
CREATE SEQUENCE seq_word start 1;
|
||||
|
||||
drop table IF EXISTS location_area CASCADE;
|
||||
CREATE TABLE location_area (
|
||||
partition integer,
|
||||
place_id BIGINT,
|
||||
country_code VARCHAR(2),
|
||||
country_code VARCHAR(2),
|
||||
keywords INTEGER[],
|
||||
rank_search INTEGER NOT NULL,
|
||||
rank_address INTEGER NOT NULL,
|
||||
@@ -96,8 +89,6 @@ SELECT AddGeometryColumn('location_area', 'centroid', 4326, 'POINT', 2);
|
||||
SELECT AddGeometryColumn('location_area', 'geometry', 4326, 'GEOMETRY', 2);
|
||||
|
||||
CREATE TABLE location_area_large () INHERITS (location_area);
|
||||
CREATE TABLE location_area_roadnear () INHERITS (location_area);
|
||||
CREATE TABLE location_area_roadfar () INHERITS (location_area);
|
||||
|
||||
drop table IF EXISTS location_property CASCADE;
|
||||
CREATE TABLE location_property (
|
||||
@@ -113,13 +104,13 @@ CREATE TABLE location_property_aux () INHERITS (location_property);
|
||||
CREATE INDEX idx_location_property_aux_place_id ON location_property_aux USING BTREE (place_id);
|
||||
CREATE INDEX idx_location_property_aux_parent_place_id ON location_property_aux USING BTREE (parent_place_id);
|
||||
CREATE INDEX idx_location_property_aux_housenumber_parent_place_id ON location_property_aux USING BTREE (parent_place_id, housenumber);
|
||||
GRANT SELECT ON location_property_aux TO "www-data";
|
||||
GRANT SELECT ON location_property_aux TO "{www-user}";
|
||||
|
||||
CREATE TABLE location_property_tiger () INHERITS (location_property);
|
||||
CREATE INDEX idx_location_property_tiger_place_id ON location_property_tiger USING BTREE (place_id);
|
||||
CREATE INDEX idx_location_property_tiger_parent_place_id ON location_property_tiger USING BTREE (parent_place_id);
|
||||
CREATE INDEX idx_location_property_tiger_housenumber_parent_place_id ON location_property_tiger USING BTREE (parent_place_id, housenumber);
|
||||
GRANT SELECT ON location_property_tiger TO "www-data";
|
||||
CREATE TABLE location_property_tiger () INHERITS (location_property) {ts:aux-data};
|
||||
CREATE INDEX idx_location_property_tiger_place_id ON location_property_tiger USING BTREE (place_id) {ts:aux-index};
|
||||
CREATE INDEX idx_location_property_tiger_parent_place_id ON location_property_tiger USING BTREE (parent_place_id) {ts:aux-index};
|
||||
CREATE INDEX idx_location_property_tiger_housenumber_parent_place_id ON location_property_tiger USING BTREE (parent_place_id, housenumber) {ts:aux-index};
|
||||
GRANT SELECT ON location_property_tiger TO "{www-user}";
|
||||
|
||||
drop table IF EXISTS search_name;
|
||||
CREATE TABLE search_name (
|
||||
@@ -130,9 +121,9 @@ CREATE TABLE search_name (
|
||||
country_code varchar(2),
|
||||
name_vector integer[],
|
||||
nameaddress_vector integer[]
|
||||
);
|
||||
) {ts:search-data};
|
||||
SELECT AddGeometryColumn('search_name', 'centroid', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_search_name_place_id ON search_name USING BTREE (place_id);
|
||||
CREATE INDEX idx_search_name_place_id ON search_name USING BTREE (place_id) {ts:search-index};
|
||||
|
||||
drop table IF EXISTS place_addressline;
|
||||
CREATE TABLE place_addressline (
|
||||
@@ -142,46 +133,10 @@ CREATE TABLE place_addressline (
|
||||
isaddress boolean,
|
||||
distance float,
|
||||
cached_rank_address integer
|
||||
);
|
||||
CREATE INDEX idx_place_addressline_place_id on place_addressline USING BTREE (place_id);
|
||||
) {ts:search-data};
|
||||
CREATE INDEX idx_place_addressline_place_id on place_addressline USING BTREE (place_id) {ts:search-index};
|
||||
|
||||
drop table IF EXISTS place_boundingbox CASCADE;
|
||||
CREATE TABLE place_boundingbox (
|
||||
place_id BIGINT,
|
||||
minlat float,
|
||||
maxlat float,
|
||||
minlon float,
|
||||
maxlon float,
|
||||
numfeatures integer,
|
||||
area float
|
||||
);
|
||||
SELECT AddGeometryColumn('place_boundingbox', 'outline', 4326, 'GEOMETRY', 2);
|
||||
GRANT SELECT on place_boundingbox to "www-data" ;
|
||||
GRANT INSERT on place_boundingbox to "www-data" ;
|
||||
|
||||
drop table IF EXISTS reverse_cache;
|
||||
CREATE TABLE reverse_cache (
|
||||
latlonzoomid integer,
|
||||
country_code varchar(2),
|
||||
place_id BIGINT
|
||||
);
|
||||
GRANT SELECT on reverse_cache to "www-data" ;
|
||||
GRANT INSERT on reverse_cache to "www-data" ;
|
||||
CREATE INDEX idx_reverse_cache_latlonzoomid ON reverse_cache USING BTREE (latlonzoomid);
|
||||
|
||||
drop table country;
|
||||
CREATE TABLE country (
|
||||
country_code varchar(2),
|
||||
country_name hstore,
|
||||
country_default_language_code varchar(2)
|
||||
);
|
||||
SELECT AddGeometryColumn('country', 'geometry', 4326, 'POLYGON', 2);
|
||||
insert into country select iso3166::varchar(2), 'name:en'->cntry_name, null,
|
||||
ST_Transform(geometryn(the_geom, generate_series(1, numgeometries(the_geom))), 4326) from worldboundaries;
|
||||
CREATE INDEX idx_country_country_code ON country USING BTREE (country_code);
|
||||
CREATE INDEX idx_country_geometry ON country USING GIST (geometry);
|
||||
|
||||
drop table placex;
|
||||
drop table if exists placex;
|
||||
CREATE TABLE placex (
|
||||
place_id BIGINT NOT NULL,
|
||||
partition integer,
|
||||
@@ -196,29 +151,24 @@ CREATE TABLE placex (
|
||||
wikipedia TEXT, -- calculated wikipedia article name (language:title)
|
||||
geometry_sector INTEGER,
|
||||
calculated_country_code varchar(2)
|
||||
);
|
||||
) {ts:search-data};
|
||||
SELECT AddGeometryColumn('placex', 'centroid', 4326, 'GEOMETRY', 2);
|
||||
CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id);
|
||||
CREATE INDEX idx_placex_osmid ON placex USING BTREE (osm_type, osm_id);
|
||||
CREATE INDEX idx_placex_linked_place_id ON placex USING BTREE (linked_place_id);
|
||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search, geometry_sector);
|
||||
CREATE INDEX idx_placex_geometry ON placex USING GIST (geometry);
|
||||
CREATE INDEX idx_placex_adminname on placex USING BTREE (make_standard_name(name->'name'),rank_search) WHERE osm_type='N' and rank_search < 26;
|
||||
CREATE UNIQUE INDEX idx_place_id ON placex USING BTREE (place_id) {ts:search-index};
|
||||
CREATE INDEX idx_placex_osmid ON placex USING BTREE (osm_type, osm_id) {ts:search-index};
|
||||
CREATE INDEX idx_placex_linked_place_id ON placex USING BTREE (linked_place_id) {ts:address-index};
|
||||
CREATE INDEX idx_placex_rank_search ON placex USING BTREE (rank_search, geometry_sector) {ts:address-index};
|
||||
CREATE INDEX idx_placex_geometry ON placex USING GIST (geometry) {ts:search-index};
|
||||
CREATE INDEX idx_placex_adminname on placex USING BTREE (make_standard_name(name->'name'),rank_search) {ts:address-index} WHERE osm_type='N' and rank_search < 26;
|
||||
|
||||
--CREATE INDEX idx_placex_indexed ON placex USING BTREE (indexed);
|
||||
|
||||
--CREATE INDEX idx_placex_pendingbylatlon ON placex USING BTREE (geometry_index(geometry_sector,indexed,name),rank_search) where geometry_index(geometry_sector,indexed,name) IS NOT NULL;
|
||||
|
||||
DROP SEQUENCE seq_place;
|
||||
DROP SEQUENCE IF EXISTS seq_place;
|
||||
CREATE SEQUENCE seq_place start 1;
|
||||
GRANT SELECT on placex to "www-data" ;
|
||||
GRANT SELECT ON search_name to "www-data" ;
|
||||
GRANT SELECT on place_addressline to "www-data" ;
|
||||
GRANT SELECT ON seq_word to "www-data" ;
|
||||
GRANT SELECT ON planet_osm_ways to "www-data" ;
|
||||
GRANT SELECT ON planet_osm_rels to "www-data" ;
|
||||
GRANT SELECT on location_area to "www-data" ;
|
||||
GRANT SELECT on country to "www-data" ;
|
||||
GRANT SELECT on placex to "{www-user}" ;
|
||||
GRANT SELECT ON search_name to "{www-user}" ;
|
||||
GRANT SELECT on place_addressline to "{www-user}" ;
|
||||
GRANT SELECT ON seq_word to "{www-user}" ;
|
||||
GRANT SELECT ON planet_osm_ways to "{www-user}" ;
|
||||
GRANT SELECT ON planet_osm_rels to "{www-user}" ;
|
||||
GRANT SELECT on location_area to "{www-user}" ;
|
||||
|
||||
-- insert creates the location tagbles, creates location indexes if indexed == true
|
||||
CREATE TRIGGER placex_before_insert BEFORE INSERT ON placex
|
||||
@@ -236,9 +186,6 @@ CREATE TRIGGER place_before_delete BEFORE DELETE ON place
|
||||
CREATE TRIGGER place_before_insert BEFORE INSERT ON place
|
||||
FOR EACH ROW EXECUTE PROCEDURE place_insert();
|
||||
|
||||
drop index idx_placex_sector;
|
||||
CREATE INDEX idx_placex_sector ON placex USING BTREE (geometry_sector,rank_address,osm_type,osm_id);
|
||||
|
||||
DROP SEQUENCE seq_postcodes;
|
||||
CREATE SEQUENCE seq_postcodes start 1;
|
||||
|
||||
@@ -256,7 +203,7 @@ CREATE TABLE import_polygon_error (
|
||||
SELECT AddGeometryColumn('import_polygon_error', 'prevgeometry', 4326, 'GEOMETRY', 2);
|
||||
SELECT AddGeometryColumn('import_polygon_error', 'newgeometry', 4326, 'GEOMETRY', 2);
|
||||
CREATE INDEX idx_import_polygon_error_osmid ON import_polygon_error USING BTREE (osm_type, osm_id);
|
||||
GRANT SELECT ON import_polygon_error TO "www-data";
|
||||
GRANT SELECT ON import_polygon_error TO "{www-user}";
|
||||
|
||||
drop table import_polygon_delete;
|
||||
CREATE TABLE import_polygon_delete (
|
||||
@@ -266,7 +213,7 @@ CREATE TABLE import_polygon_delete (
|
||||
type TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX idx_import_polygon_delete_osmid ON import_polygon_delete USING BTREE (osm_type, osm_id);
|
||||
GRANT SELECT ON import_polygon_delete TO "www-data";
|
||||
GRANT SELECT ON import_polygon_delete TO "{www-user}";
|
||||
|
||||
drop sequence file;
|
||||
CREATE SEQUENCE file start 1;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
CREATE INDEX idx_location_property_tiger_housenumber_parent_place_id_imp ON location_property_tiger_import (parent_place_id, housenumber);
|
||||
CREATE UNIQUE INDEX idx_location_property_tiger_place_id_imp ON location_property_tiger_import (place_id);
|
||||
CREATE INDEX idx_location_property_tiger_housenumber_parent_place_id_imp ON location_property_tiger_import (parent_place_id, housenumber) {ts:aux-index};
|
||||
CREATE UNIQUE INDEX idx_location_property_tiger_place_id_imp ON location_property_tiger_import (place_id) {ts:aux-index};
|
||||
|
||||
GRANT SELECT ON location_property_tiger_import TO "www-data";
|
||||
GRANT SELECT ON location_property_tiger_import TO "{www-user}";
|
||||
|
||||
DROP TABLE location_property_tiger;
|
||||
DROP TABLE IF EXISTS location_property_tiger;
|
||||
ALTER TABLE location_property_tiger_import RENAME TO location_property_tiger;
|
||||
|
||||
ALTER INDEX idx_location_property_tiger_housenumber_parent_place_id_imp RENAME TO idx_location_property_tiger_housenumber_parent_place_id;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
DROP TABLE IF EXISTS location_property_tiger_import;
|
||||
CREATE TABLE location_property_tiger_import () INHERITS (location_property);
|
||||
CREATE TABLE location_property_tiger_import () INHERITS (location_property) {ts:aux-data};
|
||||
|
||||
CREATE OR REPLACE FUNCTION tigger_create_interpolation(linegeo GEOMETRY, in_startnumber INTEGER,
|
||||
in_endnumber INTEGER, interpolationtype TEXT,
|
||||
|
||||
14
sql/words.sql
Normal file
14
sql/words.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
CREATE TABLE word_frequencies AS
|
||||
(SELECT unnest(make_keywords(v)) as id, sum(count) as count
|
||||
FROM (select svals(name) as v, count(*)from place group by v) cnt
|
||||
WHERE v is not null
|
||||
GROUP BY id);
|
||||
|
||||
select count(make_keywords(v)) from (select distinct postcode as v from place) as w where v is not null;
|
||||
select count(getorcreate_housenumber_id(make_standard_name(v))) from (select distinct housenumber as v from place where housenumber is not null) as w;
|
||||
|
||||
-- copy the word frequencies
|
||||
update word set search_name_count = count from word_frequencies wf where wf.id = word.word_id;
|
||||
|
||||
-- and drop the temporary frequency table again
|
||||
drop table word_frequencies;
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Nominatim;
|
||||
require 'lib/lib.php';
|
||||
require '../lib/lib.php';
|
||||
|
||||
|
||||
class NominatimTest extends \PHPUnit_Framework_TestCase
|
||||
@@ -74,4 +74,78 @@ class NominatimTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function test_getWordSets()
|
||||
{
|
||||
|
||||
// given an array of arrays like
|
||||
// array( array('a','b'), array('c','d') )
|
||||
// returns a summary as string: '(a|b),(c|d)'
|
||||
function serialize_sets($aSets)
|
||||
{
|
||||
$aParts = array();
|
||||
foreach($aSets as $aSet){
|
||||
$aParts[] = '(' . join('|', $aSet) . ')';
|
||||
}
|
||||
return join(',', $aParts);
|
||||
}
|
||||
|
||||
$this->assertEquals(
|
||||
array(array('')),
|
||||
getWordSets(array(),0)
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'(a)',
|
||||
serialize_sets( getWordSets(array("a"),0) )
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'(a b),(a|b)',
|
||||
serialize_sets( getWordSets(array('a','b'),0) )
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'(a b c),(a|b c),(a|b|c),(a b|c)',
|
||||
serialize_sets( getWordSets(array('a','b','c'),0) )
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'(a b c d),(a|b c d),(a|b|c d),(a|b|c|d),(a|b c|d),(a b|c d),(a b|c|d),(a b c|d)',
|
||||
serialize_sets( getWordSets(array('a','b','c','d'),0) )
|
||||
);
|
||||
|
||||
|
||||
// Inverse
|
||||
$this->assertEquals(
|
||||
'(a b c),(c|a b),(c|b|a),(b c|a)',
|
||||
serialize_sets( getInverseWordSets(array('a','b','c'),0) )
|
||||
);
|
||||
|
||||
|
||||
// make sure we don't create too many sets
|
||||
// 4 words => 8 sets
|
||||
// 10 words => 511 sets
|
||||
// 15 words => 12911 sets
|
||||
// 18 words => 65536 sets
|
||||
// 20 words => 169766 sets
|
||||
// 22 words => 401930 sets
|
||||
// 28 words => 3505699 sets (needs more than 4GB via 'phpunit -d memory_limit=' to run)
|
||||
$this->assertEquals(
|
||||
8,
|
||||
count( getWordSets(array_fill( 0, 4, 'a'),0) )
|
||||
);
|
||||
|
||||
|
||||
$this->assertEquals(
|
||||
65536,
|
||||
count( getWordSets(array_fill( 0, 18, 'a'),0) )
|
||||
);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ https://phpunit.de/manual/4.2/en/
|
||||
installed.
|
||||
|
||||
To execute the test suite run
|
||||
$ phpunit
|
||||
$ cd tests-php
|
||||
$ phpunit ./
|
||||
|
||||
It will read phpunit.xml which points to the library, test path, bootstrap
|
||||
strip and set other parameters.
|
||||
|
||||
@@ -15,13 +15,17 @@ Prerequisites
|
||||
* nose (https://nose.readthedocs.org)
|
||||
* pytidylib (http://countergram.com/open-source/pytidylib)
|
||||
* haversine (https://github.com/mapado/haversine)
|
||||
* shapely (https://github.com/Toblerity/Shapely)
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
* get prerequisites
|
||||
|
||||
# on a fresh Ubuntu LTS 14.04 you'll also need these system-wide packages
|
||||
[sudo] apt-get install python-dev python-pip python-Levenshtein tidy
|
||||
|
||||
[sudo] pip install lettuce nose pytidylib haversine psycopg2
|
||||
[sudo] pip install lettuce nose pytidylib haversine psycopg2 shapely
|
||||
|
||||
* run the tests
|
||||
|
||||
|
||||
15
tests/features/api/lookup.feature
Normal file
15
tests/features/api/lookup.feature
Normal file
@@ -0,0 +1,15 @@
|
||||
Feature: Places by osm_type and osm_id Tests
|
||||
Simple tests for internal server errors and response format.
|
||||
|
||||
Scenario: address lookup for existing node, way, relation
|
||||
When looking up xml places N158845944,W72493656,,R62422,X99,N0
|
||||
Then the result is valid xml
|
||||
exactly 3 results are returned
|
||||
When looking up json places N158845944,W72493656,,R62422,X99,N0
|
||||
Then the result is valid json
|
||||
exactly 3 results are returned
|
||||
|
||||
Scenario: address lookup for non-existing or invalid node, way, relation
|
||||
When looking up xml places X99,,N0,nN158845944,ABC,,W9
|
||||
Then the result is valid xml
|
||||
exactly 0 results are returned
|
||||
@@ -1,19 +1,6 @@
|
||||
Feature: API regression tests
|
||||
Tests error cases reported in tickets.
|
||||
|
||||
@poldi-only
|
||||
Scenario Outline: github #36
|
||||
When sending json search query "<query>" with address
|
||||
Then result addresses contain
|
||||
| ID | road | city
|
||||
| 0 | Seegasse | Gemeinde Wieselburg-Land
|
||||
|
||||
Examples:
|
||||
| query
|
||||
| Seegasse, Gemeinde Wieselburg-Land
|
||||
| Seegasse, Wieselburg-Land
|
||||
| Seegasse, Wieselburg
|
||||
|
||||
Scenario: trac #2430
|
||||
When sending json search query "89 River Avenue, Hoddesdon, Hertfordshire, EN11 0JT"
|
||||
Then at least 1 result is returned
|
||||
@@ -177,3 +164,55 @@ Feature: API regression tests
|
||||
Then results contain
|
||||
| ID | class | latlon
|
||||
| 0 | highway | 51.8324206,1.2447352 +-100m
|
||||
|
||||
Scenario Outline: trac #5025
|
||||
When sending json search query "Kriegsstr <house_nr>, Karlsruhe" with address
|
||||
Then result addresses contain
|
||||
| house_number | road
|
||||
| <house_nr> | Kriegsstraße
|
||||
|
||||
Examples:
|
||||
| house_nr
|
||||
| 5c
|
||||
| 25
|
||||
| 78
|
||||
| 80
|
||||
| 99
|
||||
| 130
|
||||
| 153
|
||||
| 196
|
||||
| 256
|
||||
| 294
|
||||
|
||||
Scenario: trac #5238
|
||||
Given the request parameters
|
||||
| bounded | viewbox
|
||||
| 1 | 0,0,-1,-1
|
||||
When sending json search query "sy"
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Scenario: trac #5274
|
||||
When sending json search query "Goedestraat 41-BS, Utrecht" with address
|
||||
Then result addresses contain
|
||||
| house_number | road | city
|
||||
| 41-BS | Goedestraat | Utrecht
|
||||
|
||||
@poldi-only
|
||||
Scenario Outline: github #36
|
||||
When sending json search query "<query>" with address
|
||||
Then result addresses contain
|
||||
| ID | road | city
|
||||
| 0 | Seegasse | Wieselburg-Land
|
||||
|
||||
Examples:
|
||||
| query
|
||||
| Seegasse, Gemeinde Wieselburg-Land
|
||||
| Seegasse, Wieselburg-Land
|
||||
| Seegasse, Wieselburg
|
||||
|
||||
Scenario: github #190
|
||||
When looking up place N257363453
|
||||
Then the results contain
|
||||
| osm_type | osm_id | latlon
|
||||
| node | 257363453 | 35.8404121,128.5586643 +-100m
|
||||
|
||||
|
||||
@@ -11,3 +11,53 @@ Feature: Reverse geocoding
|
||||
| ID | country
|
||||
| 0 | Deutschland
|
||||
|
||||
@Tiger
|
||||
Scenario: TIGER house number
|
||||
Given the request parameters
|
||||
| addressdetails
|
||||
| 1
|
||||
When looking up coordinates 40.6863624710666,-112.060005720023
|
||||
And exactly 1 result is returned
|
||||
And result addresses contain
|
||||
| ID | house_number | road | postcode | country_code
|
||||
| 0 | 7094 | Kings Estate Drive | 84128 | us
|
||||
And result 0 has not attributes osm_id,osm_type
|
||||
|
||||
|
||||
@Tiger
|
||||
Scenario: No TIGER house number for zoom < 18
|
||||
Given the request parameters
|
||||
| addressdetails | zoom
|
||||
| 1 | 17
|
||||
When looking up coordinates 40.6863624710666,-112.060005720023
|
||||
And exactly 1 result is returned
|
||||
And result addresses contain
|
||||
| ID | road | postcode | country_code
|
||||
| 0 | Kings Estate Drive | 84128 | us
|
||||
And result 0 has attributes osm_id,osm_type
|
||||
|
||||
Scenario Outline: Reverse Geocoding with extratags
|
||||
Given the request parameters
|
||||
| extratags
|
||||
| 1
|
||||
When looking up <format> coordinates 48.86093,2.2978
|
||||
Then result 0 has attributes extratags
|
||||
|
||||
Examples:
|
||||
| format
|
||||
| xml
|
||||
| json
|
||||
| jsonv2
|
||||
|
||||
Scenario Outline: Reverse Geocoding with namedetails
|
||||
Given the request parameters
|
||||
| namedetails
|
||||
| 1
|
||||
When looking up <format> coordinates 48.86093,2.2978
|
||||
Then result 0 has attributes namedetails
|
||||
|
||||
Examples:
|
||||
| format
|
||||
| xml
|
||||
| json
|
||||
| jsonv2
|
||||
|
||||
13
tests/features/api/reverse_by_id.feature
Normal file
13
tests/features/api/reverse_by_id.feature
Normal file
@@ -0,0 +1,13 @@
|
||||
Feature: Reverse lookup by ID
|
||||
Testing reverse geocoding via OSM ID
|
||||
|
||||
# see github issue #269
|
||||
Scenario: Get address of linked places
|
||||
Given the request parameters
|
||||
| osm_type | osm_id
|
||||
| N | 151421301
|
||||
When sending an API call reverse
|
||||
Then exactly 1 result is returned
|
||||
And result addresses contain
|
||||
| county | state
|
||||
| Pratt County | Kansas
|
||||
@@ -50,3 +50,48 @@ Feature: Simple Reverse Tests
|
||||
Then the result is valid json
|
||||
When looking up jsonv2 coordinates 36.791966,127.171726
|
||||
Then the result is valid json
|
||||
|
||||
Scenario: Missing lon parameter
|
||||
Given the request parameters
|
||||
| lat
|
||||
| 51.51
|
||||
When sending an API call reverse
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Scenario: Missing lat parameter
|
||||
Given the request parameters
|
||||
| lon
|
||||
| -79.39114
|
||||
When sending an API call reverse
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Scenario: Missing osm_id parameter
|
||||
Given the request parameters
|
||||
| osm_type
|
||||
| N
|
||||
When sending an API call reverse
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Scenario: Missing osm_type parameter
|
||||
Given the request parameters
|
||||
| osm_id
|
||||
| 3498564
|
||||
When sending an API call reverse
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Scenario Outline: Bad format for lat or lon
|
||||
Given the request parameters
|
||||
| lat | lon |
|
||||
| <lat> | <lon> |
|
||||
When sending an API call reverse
|
||||
Then exactly 0 results are returned
|
||||
|
||||
Examples:
|
||||
| lat | lon
|
||||
| 48.9660 | 8,4482
|
||||
| 48,9660 | 8.4482
|
||||
| 48,9660 | 8,4482
|
||||
| 48.966.0 | 8.4482
|
||||
| 48.966 | 8.448.2
|
||||
| Nan | 8.448
|
||||
| 48.966 | Nan
|
||||
@@ -16,17 +16,17 @@ Feature: Search queries
|
||||
Scenario: House number search for non-street address
|
||||
Given the request parameters
|
||||
| accept-language
|
||||
| en
|
||||
When sending json search query "4 Pomocnia, Poland" with address
|
||||
Then address of result 0 is
|
||||
| en
|
||||
When sending json search query "4 Pomocnia, Pokrzywnica, Poland" with address
|
||||
Then address of result 0 contains
|
||||
| type | value
|
||||
| house_number | 4
|
||||
| suburb | Pomocnia
|
||||
| county | gmina Pokrzywnica
|
||||
| state | Masovian Voivodeship
|
||||
| postcode | 06-121
|
||||
| country | Poland
|
||||
| country_code | pl
|
||||
Then address of result 0 does not contain road
|
||||
|
||||
Scenario: House number interpolation even
|
||||
Given the request parameters
|
||||
@@ -36,7 +36,7 @@ Feature: Search queries
|
||||
Then address of result 0 contains
|
||||
| type | value
|
||||
| house_number | 140
|
||||
| road | rue Don Bosco
|
||||
| road | [Rr]ue Don Bosco
|
||||
| city | Saguenay
|
||||
| state | Quebec
|
||||
| country | Canada
|
||||
@@ -50,16 +50,18 @@ Feature: Search queries
|
||||
Then address of result 0 contains
|
||||
| type | value
|
||||
| house_number | 141
|
||||
| road | rue Don Bosco
|
||||
| road | [rR]ue Don Bosco
|
||||
| city | Saguenay
|
||||
| state | Quebec
|
||||
| country | Canada
|
||||
| country_code | ca
|
||||
|
||||
@Tiger
|
||||
Scenario: TIGER house number
|
||||
When sending json search query "3 West Victory Way, Craig"
|
||||
Then result 0 has not attributes osm_id,osm_type
|
||||
|
||||
@Tiger
|
||||
Scenario: TIGER house number (road fallback)
|
||||
When sending json search query "3030 West Victory Way, Craig"
|
||||
Then result 0 has attributes osm_id,osm_type
|
||||
@@ -72,3 +74,9 @@ Feature: Search queries
|
||||
Then results contain
|
||||
| ID | display_name
|
||||
| 0 | Illinois.*
|
||||
|
||||
Scenario: Search with class-type feature
|
||||
When sending jsonv2 search query "Hotel California"
|
||||
Then results contain
|
||||
| place_rank
|
||||
| 30
|
||||
|
||||
@@ -2,6 +2,9 @@ Feature: Result order for Geocoding
|
||||
Testing that importance ordering returns sensible results
|
||||
|
||||
Scenario Outline: city order in street search
|
||||
Given the request parameters
|
||||
| limit
|
||||
| 100
|
||||
When sending json search query "<street>, <city>" with address
|
||||
Then address of result 0 contains
|
||||
| type | value
|
||||
|
||||
@@ -27,9 +27,9 @@ Feature: Search queries
|
||||
|
||||
Scenario: XML search with addressdetails
|
||||
When sending xml search query "Inuvik" with address
|
||||
Then address of result 0 is
|
||||
Then address of result 0 contains
|
||||
| type | value
|
||||
| town | Inuvik
|
||||
| city | Inuvik
|
||||
| state | Northwest Territories
|
||||
| country | Canada
|
||||
| country_code | ca
|
||||
@@ -41,7 +41,7 @@ Feature: Search queries
|
||||
| 0 | leisure | hackerspace
|
||||
And result addresses contain
|
||||
| ID | address29
|
||||
| 0 | foobar
|
||||
| 0 | Chaospott
|
||||
And address of result 0 does not contain leisure,hackerspace
|
||||
|
||||
Scenario: Disabling deduplication
|
||||
@@ -70,7 +70,7 @@ Feature: Search queries
|
||||
Then result addresses contain
|
||||
| ID | city
|
||||
| 0 | Chicago
|
||||
|
||||
|
||||
Scenario: No POI search with unbounded viewbox
|
||||
Given the request parameters
|
||||
| viewbox
|
||||
@@ -83,7 +83,7 @@ Feature: Search queries
|
||||
Scenario: bounded search remains within viewbox, even with no results
|
||||
Given the request parameters
|
||||
| bounded | viewbox
|
||||
| 1 | -5.662003,43.54285,-5.6563282,43.5403125
|
||||
| 1 | 43.54285,-5.662003,43.5403125,-5.6563282
|
||||
When sending json search query "restaurant"
|
||||
Then less than 1 result is returned
|
||||
|
||||
@@ -170,3 +170,63 @@ Feature: Search queries
|
||||
Then results contain
|
||||
| ID | display_name
|
||||
| 0 | Everest.*
|
||||
|
||||
Scenario Outline: Search with polygon threshold (json)
|
||||
Given the request parameters
|
||||
| polygon_geojson | polygon_threshold
|
||||
| 1 | <th>
|
||||
When sending json search query "switzerland"
|
||||
Then at least 1 result is returned
|
||||
And result 0 has attributes geojson
|
||||
|
||||
Examples:
|
||||
| th
|
||||
| -1
|
||||
| 0.0
|
||||
| 0.5
|
||||
| 999
|
||||
| nan
|
||||
|
||||
Scenario Outline: Search with polygon threshold (xml)
|
||||
Given the request parameters
|
||||
| polygon_geojson | polygon_threshold
|
||||
| 1 | <th>
|
||||
When sending xml search query "switzerland"
|
||||
Then at least 1 result is returned
|
||||
And result 0 has attributes geojson
|
||||
|
||||
Examples:
|
||||
| th
|
||||
| -1
|
||||
| 0.0
|
||||
| 0.5
|
||||
| 999
|
||||
| nan
|
||||
|
||||
Scenario Outline: Search with extratags
|
||||
Given the request parameters
|
||||
| extratags
|
||||
| 1
|
||||
When sending <format> search query "Hauptstr"
|
||||
Then result 0 has attributes extratags
|
||||
And result 1 has attributes extratags
|
||||
|
||||
Examples:
|
||||
| format
|
||||
| xml
|
||||
| json
|
||||
| jsonv2
|
||||
|
||||
Scenario Outline: Search with namedetails
|
||||
Given the request parameters
|
||||
| namedetails
|
||||
| 1
|
||||
When sending <format> search query "Hauptstr"
|
||||
Then result 0 has attributes namedetails
|
||||
And result 1 has attributes namedetails
|
||||
|
||||
Examples:
|
||||
| format
|
||||
| xml
|
||||
| json
|
||||
| jsonv2
|
||||
|
||||
@@ -51,6 +51,10 @@ Feature: Simple Tests
|
||||
| limit | 1000
|
||||
| dedupe | 1
|
||||
| dedupe | 0
|
||||
| extratags | 1
|
||||
| extratags | 0
|
||||
| namedetails | 1
|
||||
| namedetails | 0
|
||||
|
||||
Scenario: Search with invalid output format
|
||||
Given the request parameters
|
||||
@@ -166,6 +170,13 @@ Feature: Simple Tests
|
||||
| attr | value
|
||||
| exclude_place_ids | 123,76,342565
|
||||
|
||||
Scenario: Empty XML search with bad exluded place ids
|
||||
Given the request parameters
|
||||
| exclude_place_ids
|
||||
| ,
|
||||
When sending xml search query "jghrleoxsbwjer"
|
||||
Then result header has no attribute exclude_place_ids
|
||||
|
||||
Scenario Outline: Wrapping of legal jsonp search requests
|
||||
Given the request parameters
|
||||
| json_callback
|
||||
|
||||
441
tests/features/db/import/interpolation.feature
Normal file
441
tests/features/db/import/interpolation.feature
Normal file
@@ -0,0 +1,441 @@
|
||||
@DB
|
||||
Feature: Import of address interpolations
|
||||
Tests that interpolated addresses are added correctly
|
||||
|
||||
Scenario: Simple even two point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 6 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.0005
|
||||
|
||||
Scenario: Simple even two point interpolation with zero beginning
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 0 | 1 1
|
||||
| 2 | place | house | 8 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 2 | 1,1.00025
|
||||
| 4 | 1,1.0005
|
||||
| 6 | 1,1.00075
|
||||
|
||||
Scenario: Backwards even two point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 6 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1.001, 1 1
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 2,1
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.0005
|
||||
|
||||
Scenario: Even two point interpolation with odd beginning
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 11 | 1 1
|
||||
| 2 | place | house | 16 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 12 | 1,1.0002
|
||||
| 14 | 1,1.0006
|
||||
|
||||
Scenario: Even two point interpolation with odd end
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 10 | 1 1
|
||||
| 2 | place | house | 15 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 12 | 1,1.0004
|
||||
| 14 | 1,1.0008
|
||||
|
||||
Scenario: Reverse even two point interpolation with odd beginning
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 11 | 1 1
|
||||
| 2 | place | house | 16 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1.001, 1 1
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 2,1
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 12 | 1,1.0002
|
||||
| 14 | 1,1.0006
|
||||
|
||||
Scenario: Reverse even two point interpolation with odd end
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 10 | 1 1
|
||||
| 2 | place | house | 15 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1.001, 1 1
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 2,1
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 12 | 1,1.0004
|
||||
| 14 | 1,1.0008
|
||||
|
||||
Scenario: Simple odd two point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 1 | 1 1
|
||||
| 2 | place | house | 11 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | odd | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 3 | 1,1.0002
|
||||
| 5 | 1,1.0004
|
||||
| 7 | 1,1.0006
|
||||
| 9 | 1,1.0008
|
||||
|
||||
Scenario: Odd two point interpolation with even beginning
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 7 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | odd | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 3 | 1,1.0002
|
||||
| 5 | 1,1.0006
|
||||
|
||||
Scenario: Simple all two point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 1 | 1 1
|
||||
| 2 | place | house | 3 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | all | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 2 | 1,1.0005
|
||||
|
||||
Scenario: Simple numbered two point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 3 | 1 1
|
||||
| 2 | place | house | 9 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | 3 | 1 1, 1 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 6 | 1,1.0005
|
||||
|
||||
Scenario: Even two point interpolation with intermediate empty node
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 10 | 1.001 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.0005
|
||||
| 6 | 1,1.001
|
||||
| 8 | 1.0005,1.001
|
||||
|
||||
|
||||
Scenario: Even two point interpolation with intermediate duplicated empty node
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 10 | 1.001 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,3,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.0005
|
||||
| 6 | 1,1.001
|
||||
| 8 | 1.0005,1.001
|
||||
|
||||
Scenario: Simple even three point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 14 | 1.001 1.001
|
||||
| 3 | place | house | 10 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.00025
|
||||
| 6 | 1,1.0005
|
||||
| 8 | 1,1.00075
|
||||
| 12 | 1.0005,1.001
|
||||
|
||||
Scenario: Simple even four point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 14 | 1.001 1.001
|
||||
| 3 | place | house | 10 | 1 1.001
|
||||
| 4 | place | house | 18 | 1.001 1.002
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001, 1.001 1.002
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,3,2,4
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.00025
|
||||
| 6 | 1,1.0005
|
||||
| 8 | 1,1.00075
|
||||
| 12 | 1.0005,1.001
|
||||
| 16 | 1.001,1.0015
|
||||
|
||||
Scenario: Reverse simple even three point interpolation
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 14 | 1.001 1.001
|
||||
| 3 | place | house | 10 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1.001 1.001, 1 1.001, 1 1
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 2,3,1
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.00025
|
||||
| 6 | 1,1.0005
|
||||
| 8 | 1,1.00075
|
||||
| 12 | 1.0005,1.001
|
||||
|
||||
Scenario: Even three point interpolation with odd center point
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 1 1
|
||||
| 2 | place | house | 8 | 1.001 1.001
|
||||
| 3 | place | house | 7 | 1 1.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 1 1, 1 1.001, 1.001 1.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 1,1.0004
|
||||
| 6 | 1,1.0008
|
||||
|
||||
Scenario: Interpolation on self-intersecting way
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 0 0
|
||||
| 2 | place | house | 6 | 0 0.001
|
||||
| 3 | place | house | 10 | 0 0.002
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 0 0, 0 0.001, 0 0.002, 0 0.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 0,0.0005
|
||||
| 8 | 0,0.0015
|
||||
|
||||
Scenario: Interpolation on self-intersecting way II
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | 0 0
|
||||
| 2 | place | house | 6 | 0 0.001
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 0 0, 0 0.001, 0 0.002, 0 0.001
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2,3,2
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 0,0.0005
|
||||
|
||||
|
||||
Scenario: addr:street on interpolation way
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
| 3 | place | house | 12 | :n-middle-w
|
||||
| 4 | place | house | 16 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | street | geometry
|
||||
| 10 | place | houses | even | | :w-middle
|
||||
| 11 | place | houses | even | Cloud Street | :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | tertiary | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | tertiary | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
| 11 | 3,200,201,202,4
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| N3 | W3
|
||||
| N4 | W3
|
||||
| W10 | W2
|
||||
| W11 | W3
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
And way 11 expands exactly to housenumbers 14
|
||||
|
||||
Scenario: addr:street on housenumber way
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | street | geometry
|
||||
| 1 | place | house | 2 | | :n-middle-w
|
||||
| 2 | place | house | 6 | | :n-middle-e
|
||||
| 3 | place | house | 12 | Cloud Street | :n-middle-w
|
||||
| 4 | place | house | 16 | Cloud Street | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 10 | place | houses | even | :w-middle
|
||||
| 11 | place | houses | even | :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | tertiary | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | tertiary | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
| 11 | 3,200,201,202,4
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| N3 | W3
|
||||
| N4 | W3
|
||||
| W10 | W2
|
||||
| W11 | W3
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
And way 11 expands exactly to housenumbers 14
|
||||
|
||||
Scenario: Geometry of points and way don't match (github #253)
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 10 | 144.9632341 -37.76163
|
||||
| 2 | place | house | 6 | 144.9630541 -37.7628174
|
||||
| 3 | shop | supermarket | 2 | 144.9629794 -37.7630755
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | even | 144.9632341 -37.76163,144.9630541 -37.7628172,144.9629794 -37.7630755
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2,3
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 4 | 144.963016723312,-37.7629464422819+-0.000005
|
||||
| 8 | 144.9631440856,-37.762223694978+-0.000005
|
||||
|
||||
Scenario: Place with missing address information
|
||||
Given the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 23 | 0.0001 0.0001
|
||||
| 2 | amenity | school | | 0.0001 0.0002
|
||||
| 3 | place | house | 29 | 0.0001 0.0004
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | houses | odd | 0.0001 0.0001,0.0001 0.0002,0.0001 0.0004
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 1 | 1,2,3
|
||||
When importing
|
||||
Then way 1 expands to housenumbers
|
||||
| housenumber | centroid
|
||||
| 25 | 0.0001,0.0002
|
||||
| 27 | 0.0001,0.0003
|
||||
@@ -2,6 +2,20 @@
|
||||
Feature: Linking of places
|
||||
Tests for correctly determining linked places
|
||||
|
||||
Scenario: Only address-describing places can be linked
|
||||
Given the scene way-area-with-center
|
||||
And the place areas
|
||||
| osm_type | osm_id | class | type | name | geometry
|
||||
| R | 13 | landuse | forest | Garbo | :area
|
||||
And the place nodes
|
||||
| osm_id | class | type | name | geometry
|
||||
| 256 | natural | peak | Garbo | :inner-C
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | linked_place_id
|
||||
| R13 | None
|
||||
| N256 | None
|
||||
|
||||
Scenario: Waterways are linked when in waterway relations
|
||||
Given the scene split-road
|
||||
And the place ways
|
||||
|
||||
@@ -167,15 +167,6 @@ Feature: Import and search of names
|
||||
| name:fi | finnish
|
||||
| name:de | local
|
||||
|
||||
Scenario: Landuse without name are ignored
|
||||
Given the place areas
|
||||
| osm_type | osm_id | class | type | geometry
|
||||
| R | 1 | natural | meadow | (0 0, 1 0, 1 1, 0 1, 0 0)
|
||||
| R | 2 | landuse | industrial | (0 0, -1 0, -1 -1, 0 -1, 0 0)
|
||||
When importing
|
||||
Then table placex has no entry for R1
|
||||
And table placex has no entry for R2
|
||||
|
||||
Scenario: Landuse with name are found
|
||||
Given the place areas
|
||||
| osm_type | osm_id | class | type | name | geometry
|
||||
|
||||
@@ -389,7 +389,7 @@ Feature: Parenting of objects
|
||||
| N3 | W2 | None | nowhere | None
|
||||
|
||||
### Scenario 20
|
||||
Scenario: POIs parent a road if and only if they are attached to it
|
||||
Scenario: POIs parent a road if they are attached to it
|
||||
Given the scene points-on-roads
|
||||
And the named place nodes
|
||||
| osm_id | class | type | street | geometry
|
||||
@@ -408,8 +408,8 @@ Feature: Parenting of objects
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W1
|
||||
| N1 | W1
|
||||
| N2 | W2
|
||||
| N3 | W1
|
||||
| N4 | W2
|
||||
|
||||
|
||||
@@ -242,37 +242,6 @@ Feature: Import into placex
|
||||
| R22 | 12 | 0
|
||||
| R23 | 20 | 0
|
||||
|
||||
Scenario Outline: minor highways droped without name, included with
|
||||
Given the scene roads-with-pois
|
||||
And a wiped database
|
||||
And the place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 1 | highway | <type> | :w-south
|
||||
And the named place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 2 | highway | <type> | :w-north
|
||||
When importing
|
||||
Then table placex has no entry for W1
|
||||
And table placex contains
|
||||
| object | rank_search | rank_address
|
||||
| W2 | <rank> | <rank>
|
||||
|
||||
Examples:
|
||||
| type | rank
|
||||
| service | 27
|
||||
| cycleway | 27
|
||||
| path | 27
|
||||
| footway | 27
|
||||
| steps | 27
|
||||
| bridleway | 27
|
||||
| track | 26
|
||||
| byway | 26
|
||||
| motorway_link | 27
|
||||
| primary_link | 27
|
||||
| trunk_link | 27
|
||||
| secondary_link| 27
|
||||
| tertiary_link | 27
|
||||
|
||||
Scenario: search and address ranks for highways correctly assigned
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
@@ -298,77 +267,43 @@ Feature: Import into placex
|
||||
| W6 | 26 | 26
|
||||
|
||||
Scenario: rank and inclusion of landuses
|
||||
Given the place nodes
|
||||
| osm_id | class | type
|
||||
| 1 | landuse | residential
|
||||
And the named place nodes
|
||||
| osm_id | class | type
|
||||
| osm_id | class | type
|
||||
| 2 | landuse | residential
|
||||
And the place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 1 | landuse | residential | 0 0, 0 1
|
||||
And the named place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 2 | landuse | residential | 1 1, 1 1.1
|
||||
And the place areas
|
||||
| osm_type | osm_id | class | type | geometry
|
||||
| W | 3 | landuse | residential | poly-area:0.1
|
||||
| R | 1 | landuse | residential | poly-area:0.01
|
||||
| R | 10 | landuse | residential | poly-area:0.5
|
||||
And the named place areas
|
||||
| osm_type | osm_id | class | type | geometry
|
||||
| W | 4 | landuse | residential | poly-area:0.1
|
||||
| R | 2 | landuse | residential | poly-area:0.05
|
||||
| R | 3 | landuse | forrest | poly-area:0.5
|
||||
When importing
|
||||
Then table placex has no entry for N1
|
||||
And table placex has no entry for W1
|
||||
And table placex has no entry for W3
|
||||
And table placex has no entry for R1
|
||||
And table placex has no entry for R10
|
||||
And table placex contains
|
||||
| object | rank_search | rank_address
|
||||
| N2 | 30 | 30
|
||||
| W2 | 30 | 30
|
||||
| W4 | 22 | 22
|
||||
| R2 | 22 | 22
|
||||
| R3 | 22 | 0
|
||||
|
||||
Scenario: rank and inclusion of naturals
|
||||
Given the place nodes
|
||||
| osm_id | class | type
|
||||
| 1 | natural | peak
|
||||
| 3 | natural | volcano
|
||||
And the named place nodes
|
||||
| osm_id | class | type
|
||||
| 2 | natural | peak
|
||||
| 4 | natural | volcano
|
||||
| 5 | natural | foobar
|
||||
And the place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 1 | natural | mountain_range | 10 10,11 11
|
||||
And the named place ways
|
||||
| osm_id | class | type | geometry
|
||||
| 2 | natural | mountain_range | 12 12,11 11
|
||||
| 3 | natural | foobar | 13 13,13.1 13
|
||||
| 4 | natural | coastline | 14 14,14.1 14
|
||||
And the place areas
|
||||
| osm_type | osm_id | class | type | geometry
|
||||
| R | 1 | natural | volcano | poly-area:0.1
|
||||
| R | 2 | natural | volcano | poly-area:1.0
|
||||
And the named place areas
|
||||
| osm_type | osm_id | class | type | geometry
|
||||
| R | 3 | natural | volcano | poly-area:0.1
|
||||
| R | 4 | natural | foobar | poly-area:0.5
|
||||
| R | 5 | natural | sea | poly-area:5.0
|
||||
| R | 6 | natural | sea | poly-area:0.01
|
||||
| R | 7 | natural | coastline | poly-area:1.0
|
||||
When importing
|
||||
Then table placex has no entry for N1
|
||||
And table placex has no entry for N3
|
||||
And table placex has no entry for W1
|
||||
And table placex has no entry for R1
|
||||
And table placex has no entry for R2
|
||||
And table placex has no entry for R7
|
||||
And table placex has no entry for W4
|
||||
And table placex contains
|
||||
| object | rank_search | rank_address
|
||||
| N2 | 18 | 0
|
||||
@@ -376,7 +311,7 @@ Feature: Import into placex
|
||||
| N5 | 30 | 30
|
||||
| W2 | 18 | 0
|
||||
| R3 | 18 | 0
|
||||
| R4 | 22 | 22
|
||||
| R4 | 22 | 0
|
||||
| R5 | 4 | 4
|
||||
| R6 | 4 | 4
|
||||
| W3 | 30 | 30
|
||||
|
||||
@@ -26,3 +26,17 @@ Feature: Creation of search terms
|
||||
Then search_name table contains
|
||||
| place_id | name_vector | nameaddress_vector
|
||||
| N1 | foo | the road
|
||||
|
||||
Scenario: Roads take over the postcode from attached houses
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
|
||||
|
||||
167
tests/features/db/update/interpolation.feature
Normal file
167
tests/features/db/update/interpolation.feature
Normal file
@@ -0,0 +1,167 @@
|
||||
@DB
|
||||
Feature: Update of address interpolations
|
||||
Test the interpolated address are updated correctly
|
||||
|
||||
Scenario: addr:street added to interpolation
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 10 | place | houses | even | :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | unclassified | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | unclassified | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| W10 | W2
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
When updating place ways
|
||||
| osm_id | class | type | housenumber | street | geometry
|
||||
| 10 | place | houses | even | Cloud Street | :w-middle
|
||||
Then way 10 expands exactly to housenumbers 4
|
||||
And table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W3
|
||||
| N2 | W3
|
||||
| W10 | W3
|
||||
|
||||
@Fail
|
||||
Scenario: addr:street added to housenumbers
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 10 | place | houses | even | :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | unclassified | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | unclassified | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| W10 | W2
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
When updating place nodes
|
||||
| osm_id | class | type | street | housenumber | geometry
|
||||
| 1 | place | house | Cloud Street| 2 | :n-middle-w
|
||||
| 2 | place | house | Cloud Street| 6 | :n-middle-e
|
||||
Then way 10 expands exactly to housenumbers 4
|
||||
And table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W3
|
||||
| N2 | W3
|
||||
| W10 | W3
|
||||
|
||||
|
||||
Scenario: interpolation tag removed
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 10 | place | houses | even | :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | unclassified | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | unclassified | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| W10 | W2
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
When marking for delete W10
|
||||
Then way 10 expands to no housenumbers
|
||||
And table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
|
||||
|
||||
Scenario: referenced road added
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | street | geometry
|
||||
| 10 | place | houses | even | Cloud Street| :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | unclassified | 'name' : 'Sun Way' | :w-north
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| W10 | W2
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
When updating place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 3 | highway | unclassified | 'name' : 'Cloud Street' | :w-south
|
||||
Then way 10 expands exactly to housenumbers 4
|
||||
And table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W3
|
||||
| N2 | W3
|
||||
| W10 | W3
|
||||
|
||||
|
||||
Scenario: referenced road deleted
|
||||
Given the scene parallel-road
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | geometry
|
||||
| 1 | place | house | 2 | :n-middle-w
|
||||
| 2 | place | house | 6 | :n-middle-e
|
||||
And the place ways
|
||||
| osm_id | class | type | housenumber | street | geometry
|
||||
| 10 | place | houses | even | Cloud Street| :w-middle
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 2 | highway | unclassified | 'name' : 'Sun Way' | :w-north
|
||||
| 3 | highway | unclassified | 'name' : 'Cloud Street' | :w-south
|
||||
And the ways
|
||||
| id | nodes
|
||||
| 10 | 1,100,101,102,2
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W3
|
||||
| N2 | W3
|
||||
| W10 | W3
|
||||
And way 10 expands exactly to housenumbers 4
|
||||
When marking for delete W3
|
||||
Then way 10 expands exactly to housenumbers 4
|
||||
And table placex contains
|
||||
| object | parent_place_id
|
||||
| N1 | W2
|
||||
| N2 | W2
|
||||
| W10 | W2
|
||||
117
tests/features/db/update/search_terms.feature
Normal file
117
tests/features/db/update/search_terms.feature
Normal file
@@ -0,0 +1,117 @@
|
||||
@DB
|
||||
Feature: Update of search terms
|
||||
Tests that search_name table is filled correctly
|
||||
|
||||
Scenario: POI-inherited postcode remains when way type is changed
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When updating place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | unclassified | North St | :w-north
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
|
||||
Scenario: POI-inherited postcode remains when way name is changed
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When updating place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | unclassified | South St | :w-north
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
|
||||
Scenario: POI-inherited postcode remains when way geometry is changed
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When updating place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | unclassified | South St | :w-south
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
|
||||
Scenario: POI-inherited postcode is added when POI postcode changes
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When updating place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 54321 | North St |:p-S1
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 54321
|
||||
|
||||
Scenario: POI-inherited postcode remains when POI geometry changes
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When updating place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S2
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
|
||||
|
||||
Scenario: POI-inherited postcode remains when another POI is deleted
|
||||
Given the scene roads-with-pois
|
||||
And the place nodes
|
||||
| osm_id | class | type | housenumber | postcode | street | geometry
|
||||
| 1 | place | house | 1 | 12345 | North St |:p-S1
|
||||
| 2 | place | house | 2 | | North St |:p-S2
|
||||
And the place ways
|
||||
| osm_id | class | type | name | geometry
|
||||
| 1 | highway | residential | North St | :w-north
|
||||
When importing
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
When marking for delete N2
|
||||
Then search_name table contains
|
||||
| place_id | nameaddress_vector
|
||||
| W1 | 12345
|
||||
@@ -2,20 +2,6 @@
|
||||
Feature: Update of simple objects
|
||||
Testing simple stuff
|
||||
|
||||
Scenario: Remove name from a landuse object
|
||||
Given the place nodes
|
||||
| osm_id | class | type | name
|
||||
| 1 | landuse | wood | 'name' : 'Foo'
|
||||
When importing
|
||||
Then table placex contains
|
||||
| object | class | type | name
|
||||
| N1 | landuse| wood | 'name' : 'Foo'
|
||||
When updating place nodes
|
||||
| osm_id | class | type
|
||||
| 1 | landuse | wood
|
||||
Then table placex has no entry for N1
|
||||
|
||||
|
||||
Scenario: Do delete small boundary features
|
||||
Given the place areas
|
||||
| osm_type | osm_id | class | type | admin_level | geometry
|
||||
|
||||
37
tests/features/osm2pgsql/import/broken.feature
Normal file
37
tests/features/osm2pgsql/import/broken.feature
Normal file
@@ -0,0 +1,37 @@
|
||||
@DB
|
||||
Feature: Import of objects with broken geometries by osm2pgsql
|
||||
|
||||
@Fail
|
||||
Scenario: Import way with double nodes
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 100 | 0 0
|
||||
| 101 | 0 0.1
|
||||
| 102 | 0.1 0.2
|
||||
And the osm ways:
|
||||
| id | tags | nodes
|
||||
| 1 | 'highway' : 'primary' | 100 101 101 102
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | geometry
|
||||
| W1 | highway | primary | (0 0, 0 0.1, 0.1 0.2)
|
||||
|
||||
Scenario: Import of ballon areas
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 1 | 0 0
|
||||
| 2 | 0 0.0001
|
||||
| 3 | 0.00001 0.0001
|
||||
| 4 | 0.00001 0
|
||||
| 5 | -0.00001 0
|
||||
And the osm ways:
|
||||
| id | tags | nodes
|
||||
| 1 | 'highway' : 'unclassified' | 1 2 3 4 1 5
|
||||
| 2 | 'highway' : 'unclassified' | 1 2 3 4 1
|
||||
| 3 | 'highway' : 'unclassified' | 1 2 3 4 3
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | geometrytype
|
||||
| W1 | ST_LineString
|
||||
| W2 | ST_Polygon
|
||||
| W3 | ST_LineString
|
||||
550
tests/features/osm2pgsql/import/tags.feature
Normal file
550
tests/features/osm2pgsql/import/tags.feature
Normal file
@@ -0,0 +1,550 @@
|
||||
@DB
|
||||
Feature: Tag evaluation
|
||||
Tests if tags are correctly imported into the place table
|
||||
|
||||
Scenario Outline: Name tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'highway' : 'yes', '<nametag>' : 'Foo'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | name
|
||||
| N1 | '<nametag>' : 'Foo'
|
||||
|
||||
Examples:
|
||||
| nametag
|
||||
| ref
|
||||
| int_ref
|
||||
| nat_ref
|
||||
| reg_ref
|
||||
| loc_ref
|
||||
| old_ref
|
||||
| iata
|
||||
| icao
|
||||
| pcode:1
|
||||
| pcode:2
|
||||
| pcode:3
|
||||
| name
|
||||
| name:de
|
||||
| name:bt-BR
|
||||
| int_name
|
||||
| int_name:xxx
|
||||
| nat_name
|
||||
| nat_name:fr
|
||||
| reg_name
|
||||
| reg_name:1
|
||||
| loc_name
|
||||
| loc_name:DE
|
||||
| old_name
|
||||
| old_name:v1
|
||||
| alt_name
|
||||
| alt_name:dfe
|
||||
| alt_name_1
|
||||
| official_name
|
||||
| short_name
|
||||
| short_name:CH
|
||||
| addr:housename
|
||||
| brand
|
||||
|
||||
Scenario Outline: operator only for shops and amenities
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'highway' : 'yes', 'operator' : 'Foo', 'name' : 'null'
|
||||
| 2 | 'shop' : 'grocery', 'operator' : 'Foo'
|
||||
| 3 | 'amenity' : 'hospital', 'operator' : 'Foo'
|
||||
| 4 | 'tourism' : 'hotel', 'operator' : 'Foo'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | name
|
||||
| N1 | 'name' : 'null'
|
||||
| N2 | 'operator' : 'Foo'
|
||||
| N3 | 'operator' : 'Foo'
|
||||
| N4 | 'operator' : 'Foo'
|
||||
|
||||
Scenario Outline: Ignored name tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'highway' : 'yes', '<nametag>' : 'Foo', 'name' : 'real'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | name
|
||||
| N1 | 'name' : 'real'
|
||||
|
||||
Examples:
|
||||
| nametag
|
||||
| name_de
|
||||
| Name
|
||||
| ref:de
|
||||
| ref_de
|
||||
| my:ref
|
||||
| br:name
|
||||
| name:prefix
|
||||
| name:source
|
||||
|
||||
Scenario: Special character in name tag
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'highway' : 'yes', 'name: de' : 'Foo', 'name' : 'real1'
|
||||
| 2 | 'highway' : 'yes', 'name:
de' : 'Foo', 'name' : 'real2'
|
||||
| 3 | 'highway' : 'yes', 'name:	de' : 'Foo', 'name:\\' : 'real3'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | name
|
||||
| N1 | 'name: de' : 'Foo', 'name' : 'real1'
|
||||
| N2 | 'name: de' : 'Foo', 'name' : 'real2'
|
||||
| N3 | 'name: de' : 'Foo', 'name:\\\\' : 'real3'
|
||||
|
||||
Scenario Outline: Included places
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | '<key>' : '<value>', 'name' : 'real'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | name
|
||||
| N1 | 'name' : 'real'
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| emergency | phone
|
||||
| tourism | information
|
||||
| historic | castle
|
||||
| military | barracks
|
||||
| natural | water
|
||||
| highway | residential
|
||||
| aerialway | station
|
||||
| aeroway | way
|
||||
| boundary | administrative
|
||||
| craft | butcher
|
||||
| leisure | playground
|
||||
| office | bookmaker
|
||||
| railway | rail
|
||||
| shop | bookshop
|
||||
| waterway | stream
|
||||
| landuse | cemetry
|
||||
| man_made | tower
|
||||
| mountain_pass | yes
|
||||
|
||||
Scenario Outline: Bridges and Tunnels take special name tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'highway' : 'road', '<key>' : 'yes', 'name' : 'Rd', '<key>:name' : 'My'
|
||||
| 2 | 'highway' : 'road', '<key>' : 'yes', 'name' : 'Rd'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| N1:highway | highway | road | 'name' : 'Rd'
|
||||
| N1:<key> | <key> | yes | 'name' : 'My'
|
||||
| N2:highway | highway | road | 'name' : 'Rd'
|
||||
And table place has no entry for N2:<key>
|
||||
|
||||
Examples:
|
||||
| key
|
||||
| bridge
|
||||
| tunnel
|
||||
|
||||
Scenario Outline: Excluded places
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | '<key>' : '<value>', 'name' : 'real'
|
||||
| 2 | 'highway' : 'motorway', 'name' : 'To Hell'
|
||||
When loading osm data
|
||||
Then table place has no entry for N1
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| emergency | yes
|
||||
| emergency | no
|
||||
| tourism | yes
|
||||
| tourism | no
|
||||
| historic | yes
|
||||
| historic | no
|
||||
| military | yes
|
||||
| military | no
|
||||
| natural | yes
|
||||
| natural | no
|
||||
| highway | no
|
||||
| highway | turning_circle
|
||||
| highway | mini_roundabout
|
||||
| highway | noexit
|
||||
| highway | crossing
|
||||
| aerialway | no
|
||||
| aerialway | pylon
|
||||
| man_made | survey_point
|
||||
| man_made | cutline
|
||||
| aeroway | no
|
||||
| amenity | no
|
||||
| bridge | no
|
||||
| craft | no
|
||||
| leisure | no
|
||||
| office | no
|
||||
| railway | no
|
||||
| railway | level_crossing
|
||||
| shop | no
|
||||
| tunnel | no
|
||||
| waterway | riverbank
|
||||
|
||||
Scenario: Some tags only are included when named
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | '<key>' : '<value>'
|
||||
| 2 | '<key>' : '<value>', 'name' : 'To Hell'
|
||||
| 3 | '<key>' : '<value>', 'ref' : '123'
|
||||
When loading osm data
|
||||
Then table place has no entry for N1
|
||||
And table place has no entry for N3
|
||||
And table place contains
|
||||
| object | class | type
|
||||
| N2 | <key> | <value>
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| landuse | residential
|
||||
| natural | meadow
|
||||
| highway | traffic_signals
|
||||
| highway | service
|
||||
| highway | cycleway
|
||||
| highway | path
|
||||
| highway | footway
|
||||
| highway | steps
|
||||
| highway | bridleway
|
||||
| highway | track
|
||||
| highway | byway
|
||||
| highway | motorway_link
|
||||
| highway | primary_link
|
||||
| highway | trunk_link
|
||||
| highway | secondary_link
|
||||
| highway | tertiary_link
|
||||
| railway | rail
|
||||
| boundary | administrative
|
||||
| waterway | stream
|
||||
|
||||
Scenario: Footways are not included if they are sidewalks
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 2 | 'highway' : 'footway', 'name' : 'To Hell', 'footway' : 'sidewalk'
|
||||
| 23 | 'highway' : 'footway', 'name' : 'x'
|
||||
When loading osm data
|
||||
Then table place has no entry for N2
|
||||
|
||||
Scenario: named junctions are included if there is no other tag
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'junction' : 'yes'
|
||||
| 2 | 'highway' : 'secondary', 'junction' : 'roundabout', 'name' : 'To Hell'
|
||||
| 3 | 'junction' : 'yes', 'name' : 'Le Croix'
|
||||
When loading osm data
|
||||
Then table place has no entry for N1
|
||||
And table place has no entry for N2:junction
|
||||
And table place contains
|
||||
| object | class | type
|
||||
| N3 | junction | yes
|
||||
|
||||
Scenario: Boundary with place tag
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 1
|
||||
| 202 | 1 1
|
||||
| 203 | 1 0
|
||||
And the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'boundary' : 'administrative', 'place' : 'city', 'name' : 'Foo' | 200 201 202 203 200
|
||||
| 4 | 'boundary' : 'administrative', 'place' : 'island','name' : 'Foo' | 200 201 202 203 200
|
||||
| 20 | 'place' : 'city', 'name' : 'ngng' | 200 201 202 203 200
|
||||
| 40 | 'place' : 'city', 'boundary' : 'statistical', 'name' : 'BB' | 200 201 202 203 200
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | extratags | type
|
||||
| W2 | boundary | 'place' : 'city' | administrative
|
||||
| W4:boundary | boundary | None | administrative
|
||||
| W4:place | place | None | island
|
||||
| W20 | place | None | city
|
||||
| W40:boundary | boundary | None | statistical
|
||||
| W40:place | place | None | city
|
||||
And table place has no entry for W2:place
|
||||
|
||||
Scenario Outline: Tags that describe a house
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 100 | '<key>' : '<value>'
|
||||
| 999 | 'amenity' : 'prison', '<key>' : '<value>'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type
|
||||
| N100 | place | house
|
||||
| N999 | amenity | prison
|
||||
And table place has no entry for N100:<key>
|
||||
And table place has no entry for N999:<key>
|
||||
And table place has no entry for N999:place
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| addr:housename | My Mansion
|
||||
| addr:housenumber | 456
|
||||
| addr:conscriptionnumber | 4
|
||||
| addr:streetnumber | 4568765
|
||||
|
||||
Scenario: Only named with no other interesting tag
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 1 | 'landuse' : 'meadow'
|
||||
| 2 | 'landuse' : 'residential', 'name' : 'important'
|
||||
| 3 | 'landuse' : 'residential', 'name' : 'important', 'place' : 'hamlet'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type
|
||||
| N2 | landuse | residential
|
||||
| N3 | place | hamlet
|
||||
And table place has no entry for N1
|
||||
And table place has no entry for N3:landuse
|
||||
|
||||
Scenario Outline: Import of postal codes
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'highway' : 'secondary', '<key>' : '<value>'
|
||||
| 11 | '<key>' : '<value>'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | postcode
|
||||
| N10 | highway | secondary | <value>
|
||||
| N11 | place | postcode | <value>
|
||||
And table place has no entry for N10:place
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| postal_code | 45736
|
||||
| postcode | xxx
|
||||
| addr:postcode | 564
|
||||
| tiger:zip_left | 00011
|
||||
| tiger:zip_right | 09123
|
||||
|
||||
Scenario: Import of street and place
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'amenity' : 'hospital', 'addr:street' : 'Foo St'
|
||||
| 20 | 'amenity' : 'hospital', 'addr:place' : 'Foo Town'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | street | addr_place
|
||||
| N10 | amenity | hospital | Foo St | None
|
||||
| N20 | amenity | hospital | None | Foo Town
|
||||
|
||||
|
||||
Scenario Outline: Import of country
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'place' : 'village', '<key>' : '<value>'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | country_code
|
||||
| N10 | place | village | <value>
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| country_code | us
|
||||
| ISO3166-1 | XX
|
||||
| is_in:country_code | __
|
||||
| addr:country | ..
|
||||
| addr:country_code | cv
|
||||
|
||||
Scenario Outline: Ignore country codes with wrong length
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'place' : 'village', 'country_code' : '<value>'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | country_code
|
||||
| N10 | place | village | None
|
||||
|
||||
Examples:
|
||||
| value
|
||||
| X
|
||||
| x
|
||||
| ger
|
||||
| dkeufr
|
||||
| d e
|
||||
|
||||
Scenario: Import of house numbers
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'building' : 'yes', 'addr:housenumber' : '4b'
|
||||
| 11 | 'building' : 'yes', 'addr:conscriptionnumber' : '003'
|
||||
| 12 | 'building' : 'yes', 'addr:streetnumber' : '2345'
|
||||
| 13 | 'building' : 'yes', 'addr:conscriptionnumber' : '3', 'addr:streetnumber' : '111'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | housenumber
|
||||
| N10 | building | yes | 4b
|
||||
| N11 | building | yes | 003
|
||||
| N12 | building | yes | 2345
|
||||
| N13 | building | yes | 3/111
|
||||
|
||||
Scenario: Import of address interpolations
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'addr:interpolation' : 'odd'
|
||||
| 11 | 'addr:housenumber' : '10', 'addr:interpolation' : 'odd'
|
||||
| 12 | 'addr:interpolation' : 'odd', 'addr:housenumber' : '23'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | housenumber
|
||||
| N10 | place | houses | odd
|
||||
| N11 | place | houses | odd
|
||||
| N12 | place | houses | odd
|
||||
|
||||
Scenario: Shorten tiger:county tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'place' : 'village', 'tiger:county' : 'Feebourgh, AL'
|
||||
| 11 | 'place' : 'village', 'addr:state' : 'Alabama', 'tiger:county' : 'Feebourgh, AL'
|
||||
| 12 | 'place' : 'village', 'tiger:county' : 'Feebourgh'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | isin
|
||||
| N10 | place | village | Feebourgh county
|
||||
| N11 | place | village | Feebourgh county,Alabama
|
||||
| N12 | place | village | Feebourgh county
|
||||
|
||||
Scenario Outline: Import of address tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'place' : 'village', '<key>' : '<value>'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | isin
|
||||
| N10 | place | village | <value>
|
||||
|
||||
Examples:
|
||||
| key | value
|
||||
| is_in | Stockholm, Sweden
|
||||
| is_in:country | Xanadu
|
||||
| addr:suburb | hinein
|
||||
| addr:county | le havre
|
||||
| addr:city | Sydney
|
||||
| addr:state | Jura
|
||||
|
||||
Scenario: Import of admin level
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'amenity' : 'hospital', 'admin_level' : '3'
|
||||
| 11 | 'amenity' : 'hospital', 'admin_level' : 'b'
|
||||
| 12 | 'amenity' : 'hospital'
|
||||
| 13 | 'amenity' : 'hospital', 'admin_level' : '3.0'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | admin_level
|
||||
| N10 | amenity | hospital | 3
|
||||
| N11 | amenity | hospital | 100
|
||||
| N12 | amenity | hospital | 100
|
||||
| N13 | amenity | hospital | 3
|
||||
|
||||
Scenario: Import of extra tags
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'tourism' : 'hotel', '<key>' : 'foo'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | extratags
|
||||
| N10 | tourism | hotel | '<key>' : 'foo'
|
||||
|
||||
Examples:
|
||||
| key
|
||||
| tracktype
|
||||
| traffic_calming
|
||||
| service
|
||||
| cuisine
|
||||
| capital
|
||||
| dispensing
|
||||
| religion
|
||||
| denomination
|
||||
| sport
|
||||
| internet_access
|
||||
| lanes
|
||||
| surface
|
||||
| smoothness
|
||||
| width
|
||||
| est_width
|
||||
| incline
|
||||
| opening_hours
|
||||
| collection_times
|
||||
| service_times
|
||||
| disused
|
||||
| wheelchair
|
||||
| sac_scale
|
||||
| trail_visibility
|
||||
| mtb:scale
|
||||
| mtb:description
|
||||
| wood
|
||||
| drive_in
|
||||
| access
|
||||
| vehicle
|
||||
| bicyle
|
||||
| foot
|
||||
| goods
|
||||
| hgv
|
||||
| motor_vehicle
|
||||
| motor_car
|
||||
| access:foot
|
||||
| contact:phone
|
||||
| drink:mate
|
||||
| oneway
|
||||
| date_on
|
||||
| date_off
|
||||
| day_on
|
||||
| day_off
|
||||
| hour_on
|
||||
| hour_off
|
||||
| maxweight
|
||||
| maxheight
|
||||
| maxspeed
|
||||
| disused
|
||||
| toll
|
||||
| charge
|
||||
| population
|
||||
| description
|
||||
| image
|
||||
| attribution
|
||||
| fax
|
||||
| email
|
||||
| url
|
||||
| website
|
||||
| phone
|
||||
| real_ale
|
||||
| smoking
|
||||
| food
|
||||
| camera
|
||||
| brewery
|
||||
| locality
|
||||
| wikipedia
|
||||
| wikipedia:de
|
||||
| wikidata
|
||||
| name:prefix
|
||||
| name:botanical
|
||||
| name:etymology:wikidata
|
||||
|
||||
Scenario: buildings
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 10 | 'tourism' : 'hotel', 'building' : 'yes'
|
||||
| 11 | 'building' : 'house'
|
||||
| 12 | 'building' : 'shed', 'addr:housenumber' : '1'
|
||||
| 13 | 'building' : 'yes', 'name' : 'Das Haus'
|
||||
| 14 | 'building' : 'yes', 'addr:postcode' : '12345'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type
|
||||
| N10 | tourism | hotel
|
||||
| N12 | building| yes
|
||||
| N13 | building| yes
|
||||
| N14 | building| yes
|
||||
And table place has no entry for N10:building
|
||||
And table place has no entry for N11
|
||||
|
||||
Scenario: complete node entry
|
||||
Given the osm nodes:
|
||||
| id | tags
|
||||
| 290393920 | 'addr:city':'Perpignan','addr:country':'FR','addr:housenumber':'43\\','addr:postcode':'66000','addr:street':'Rue Pierre Constant d`Ivry','source':'cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre ; mise à jour :2008'
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | housenumber
|
||||
| N290393920 | place | house| 43\
|
||||
@@ -28,3 +28,125 @@ Scenario: Remove all members of a relation
|
||||
When updating osm data
|
||||
Then table place has no entry for R1
|
||||
|
||||
|
||||
Scenario: Change type of a relation
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 0.0001
|
||||
| 202 | 0.0001 0.0001
|
||||
| 203 | 0.0001 0
|
||||
Given the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'ref' : '45' | 200 201 202 203 200
|
||||
Given the osm relations:
|
||||
| id | tags | members
|
||||
| 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'XZ'
|
||||
Given the osm relations:
|
||||
| action | id | tags | members
|
||||
| M | 1 | 'type' : 'multipolygon', 'amenity' : 'prison', 'name' : 'XZ' | W2
|
||||
When updating osm data
|
||||
Then table place has no entry for R1:tourism
|
||||
And table place contains
|
||||
| object | class | type | name
|
||||
| R1 | amenity | prison | 'name' : 'XZ'
|
||||
|
||||
Scenario: Change name of a relation
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 0.0001
|
||||
| 202 | 0.0001 0.0001
|
||||
| 203 | 0.0001 0
|
||||
Given the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'ref' : '45' | 200 201 202 203 200
|
||||
Given the osm relations:
|
||||
| id | tags | members
|
||||
| 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'AB' | W2
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'AB'
|
||||
Given the osm relations:
|
||||
| action | id | tags | members
|
||||
| M | 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When updating osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'XZ'
|
||||
|
||||
|
||||
Scenario: Change type of a relation into something unknown
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 0.0001
|
||||
| 202 | 0.0001 0.0001
|
||||
| 203 | 0.0001 0
|
||||
Given the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'ref' : '45' | 200 201 202 203 200
|
||||
Given the osm relations:
|
||||
| id | tags | members
|
||||
| 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'XZ'
|
||||
Given the osm relations:
|
||||
| action | id | tags | members
|
||||
| M | 1 | 'type' : 'multipolygon', 'amenities' : 'prison', 'name' : 'XZ' | W2
|
||||
When updating osm data
|
||||
Then table place has no entry for R1
|
||||
|
||||
Scenario: Type tag is removed
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 0.0001
|
||||
| 202 | 0.0001 0.0001
|
||||
| 203 | 0.0001 0
|
||||
Given the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'ref' : '45' | 200 201 202 203 200
|
||||
Given the osm relations:
|
||||
| id | tags | members
|
||||
| 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'XZ'
|
||||
Given the osm relations:
|
||||
| action | id | tags | members
|
||||
| M | 1 | 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When updating osm data
|
||||
Then table place has no entry for R1
|
||||
|
||||
Scenario: Type tag is renamed to something unknown
|
||||
Given the osm nodes:
|
||||
| id | geometry
|
||||
| 200 | 0 0
|
||||
| 201 | 0 0.0001
|
||||
| 202 | 0.0001 0.0001
|
||||
| 203 | 0.0001 0
|
||||
Given the osm ways:
|
||||
| id | tags | nodes
|
||||
| 2 | 'ref' : '45' | 200 201 202 203 200
|
||||
Given the osm relations:
|
||||
| id | tags | members
|
||||
| 1 | 'type' : 'multipolygon', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When loading osm data
|
||||
Then table place contains
|
||||
| object | class | type | name
|
||||
| R1 | tourism | hotel | 'name' : 'XZ'
|
||||
Given the osm relations:
|
||||
| action | id | tags | members
|
||||
| M | 1 | 'type' : 'multipolygonn', 'tourism' : 'hotel', 'name' : 'XZ' | W2
|
||||
When updating osm data
|
||||
Then table place has no entry for R1
|
||||
|
||||
|
||||
26
tests/scenes/bin/Makefile
Normal file
26
tests/scenes/bin/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
CXXFLAGS += -O3
|
||||
#CXXFLAGS += -g
|
||||
CXXFLAGS += -std=c++11 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
|
||||
CXXFLAGS += -I../../../../libosmium/include
|
||||
|
||||
OS:=$(shell uname -s)
|
||||
ifeq ($(OS),Darwin)
|
||||
CXXFLAGS += -stdlib=libc++
|
||||
LDFLAGS += -stdlib=libc++
|
||||
endif
|
||||
|
||||
CXXFLAGS_WARNINGS := -Wall -Wextra -pedantic -Wredundant-decls -Wdisabled-optimization -Wctor-dtor-privacy -Wnon-virtual-dtor -Woverloaded-virtual -Wsign-promo -Wold-style-cast
|
||||
|
||||
LIB_EXPAT := -lexpat
|
||||
LIB_PBF := -pthread -lz -lprotobuf-lite -losmpbf
|
||||
LIB_GZIP := -lz
|
||||
LIB_BZIP2 := -lbz2
|
||||
|
||||
LIB_IO := $(LIB_EXPAT) $(LIB_PBF) $(LIB_GZIP) $(LIB_BZIP2)
|
||||
|
||||
all:
|
||||
|
||||
osm2wkt: osm2wkt.cc
|
||||
$(CXX) $(CXXFLAGS) $(CXXFLAGS_WARNINGS) -o $@ $< $(LDFLAGS) $(LIB_IO)
|
||||
|
||||
scenarios: osm2wkt
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
datadir="$( cd "$( dirname "$0" )" && cd ../data && pwd )"
|
||||
|
||||
if [! -d "$datadir" ]; then
|
||||
if [ ! -d "$datadir" ]; then
|
||||
echo "Cannot find data dir.";
|
||||
exit -1;
|
||||
fi
|
||||
|
||||
@@ -7,23 +7,23 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include <osmium/area/assembler.hpp>
|
||||
#include <osmium/area/collector.hpp>
|
||||
#include <osmium/area/multipolygon_collector.hpp>
|
||||
#include <osmium/area/problem_reporter_exception.hpp>
|
||||
#include <osmium/geom/wkt.hpp>
|
||||
#include <osmium/handler.hpp>
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/io/any_input.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
#include <osmium/index/map/stl_map.hpp>
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
typedef osmium::index::map::StlMap<osmium::unsigned_object_id_type, osmium::Location> index_type;
|
||||
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
|
||||
|
||||
typedef osmium::handler::NodeLocationsForWays<index_type, index_type> location_handler_type;
|
||||
|
||||
|
||||
class ExportToWKTHandler : public osmium::handler::Handler {
|
||||
|
||||
osmium::geom::WKTFactory m_factory;
|
||||
osmium::geom::WKTFactory<> m_factory;
|
||||
std::unordered_map<std::string, std::ofstream> m_files;
|
||||
|
||||
public:
|
||||
@@ -70,13 +70,12 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
std::string input_filename {argv[1]};
|
||||
|
||||
typedef osmium::area::Assembler area_assembler_type;
|
||||
osmium::area::ProblemReporterException problem_reporter;
|
||||
area_assembler_type assembler(&problem_reporter);
|
||||
osmium::area::Collector<area_assembler_type> collector(assembler);
|
||||
osmium::area::Assembler::config_type assembler_config(&problem_reporter);
|
||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
|
||||
|
||||
std::cerr << "Pass 1...\n";
|
||||
osmium::io::Reader reader1(input_filename);
|
||||
osmium::io::Reader reader1(input_filename, osmium::osm_entity_bits::relation);
|
||||
collector.read_relations(reader1);
|
||||
std::cerr << "Pass 1 done\n";
|
||||
|
||||
@@ -87,9 +86,10 @@ int main(int argc, char* argv[]) {
|
||||
std::cerr << "Pass 2...\n";
|
||||
ExportToWKTHandler export_handler;
|
||||
osmium::io::Reader reader2(input_filename);
|
||||
osmium::apply(reader2, location_handler, export_handler, collector.handler());
|
||||
osmium::apply(reader2, location_handler, export_handler, collector.handler([&export_handler](osmium::memory::Buffer&& buffer) {
|
||||
osmium::apply(buffer, export_handler);
|
||||
}));
|
||||
reader2.close();
|
||||
osmium::apply(collector, export_handler);
|
||||
export_handler.close();
|
||||
std::cerr << "Pass 2 done\n";
|
||||
|
||||
|
||||
5
tests/scenes/data/parallel-road.wkt
Normal file
5
tests/scenes/data/parallel-road.wkt
Normal file
@@ -0,0 +1,5 @@
|
||||
n-middle-w | POINT(1.0065316 2.0003381)
|
||||
n-middle-e | POINT(1.007236 2.0003408)
|
||||
w-south | LINESTRING(1.0065324 2.0001892,1.006676 2.0002786,1.0068195 2.0002786,1.0069171 2.0002515,1.0070417 2.0001892,1.0072422 2.000173)
|
||||
w-middle | LINESTRING(1.0065316 2.0003381,1.006686 2.0004248,1.0069 2.0004167,1.007236 2.0003408)
|
||||
w-north | LINESTRING(1.0065397 2.000418,1.0066833 2.0005074,1.0068269 2.0005074,1.0069244 2.0004803,1.007049 2.000418,1.0072495 2.0004018)
|
||||
@@ -1,168 +1,221 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osm version='0.6'>
|
||||
<node id="100" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="101" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="102" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.001" />
|
||||
<node id="103" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.001" />
|
||||
<way id="100" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="100" />
|
||||
<nd ref="101" />
|
||||
<nd ref="102" />
|
||||
<nd ref="103" />
|
||||
<nd ref="100" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.0001"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="200" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="201" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="202" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.005" />
|
||||
<node id="203" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.005" />
|
||||
<way id="200" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="200" />
|
||||
<nd ref="201" />
|
||||
<nd ref="202" />
|
||||
<nd ref="203" />
|
||||
<nd ref="200" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.0005"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="300" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="301" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="302" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.01" />
|
||||
<node id="303" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.01" />
|
||||
<way id="300" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="300" />
|
||||
<nd ref="301" />
|
||||
<nd ref="302" />
|
||||
<nd ref="303" />
|
||||
<nd ref="300" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.001"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="400" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="401" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="402" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.05" />
|
||||
<node id="403" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.05" />
|
||||
<way id="400" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="400" />
|
||||
<nd ref="401" />
|
||||
<nd ref="402" />
|
||||
<nd ref="403" />
|
||||
<nd ref="400" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.005"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="500" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="501" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="502" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.1" />
|
||||
<node id="503" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.1" />
|
||||
<way id="500" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="500" />
|
||||
<nd ref="501" />
|
||||
<nd ref="502" />
|
||||
<nd ref="503" />
|
||||
<nd ref="500" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.01"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="600" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="601" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.0" />
|
||||
<node id="602" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.1" lon="0.5" />
|
||||
<node id="603" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.5" />
|
||||
<way id="600" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="600" />
|
||||
<nd ref="601" />
|
||||
<nd ref="602" />
|
||||
<nd ref="603" />
|
||||
<nd ref="600" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.05"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="700" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="701" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.0" />
|
||||
<node id="702" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.1" />
|
||||
<node id="703" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.1" />
|
||||
<way id="700" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="700" />
|
||||
<nd ref="701" />
|
||||
<nd ref="702" />
|
||||
<nd ref="703" />
|
||||
<nd ref="700" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.1"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="800" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="801" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.0" />
|
||||
<node id="802" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.5" />
|
||||
<node id="803" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.5" />
|
||||
<way id="800" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="800" />
|
||||
<nd ref="801" />
|
||||
<nd ref="802" />
|
||||
<nd ref="803" />
|
||||
<nd ref="800" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="0.5"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="900" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="901" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.0" />
|
||||
<node id="902" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="1.0" />
|
||||
<node id="903" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="1.0" />
|
||||
<way id="900" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="900" />
|
||||
<nd ref="901" />
|
||||
<nd ref="902" />
|
||||
<nd ref="903" />
|
||||
<nd ref="900" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="1.0"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="1000" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="1001" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.0" />
|
||||
<node id="1002" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="2.0" />
|
||||
<node id="1003" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="2.0" />
|
||||
<way id="1000" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="1000" />
|
||||
<nd ref="1001" />
|
||||
<nd ref="1002" />
|
||||
<nd ref="1003" />
|
||||
<nd ref="1000" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="2.0"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<node id="1100" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="0.0" />
|
||||
<node id="1101" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="0.0" />
|
||||
<node id="1102" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="1.0" lon="5.0" />
|
||||
<node id="1103" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1" lat="0.0" lon="5.0" />
|
||||
<way id="1100" version="1" timestamp="2014-01-01T00:00:00Z" uid="1" user="test" changeset="1">
|
||||
<nd ref="1100" />
|
||||
<nd ref="1101" />
|
||||
<nd ref="1102" />
|
||||
<nd ref="1103" />
|
||||
<nd ref="1100" />
|
||||
<tag k="test:section" v="poly-area"/>
|
||||
<tag k="test:id" v="5.0"/>
|
||||
<tag k="area" v="yes"/>
|
||||
</way>
|
||||
|
||||
<osm version='0.6' upload='true' generator='JOSM'>
|
||||
<node id='-238' action='modify' visible='true' lat='-0.00661880152' lon='0.00356249245'>
|
||||
<tag k='test:id' v='inner-C' />
|
||||
<tag k='test:section' v='way-area-with-center' />
|
||||
</node>
|
||||
<node id='-231' action='modify' visible='true' lat='-0.00600066098' lon='0.0041244384'>
|
||||
<tag k='test:id' v='outer-C' />
|
||||
<tag k='test:section' v='way-area-with-center' />
|
||||
</node>
|
||||
<node id='-225' action='modify' visible='true' lat='-0.00236518426' lon='0.00188464186'>
|
||||
<tag k='test:id' v='inner-N' />
|
||||
<tag k='test:section' v='way-area-with-center' />
|
||||
</node>
|
||||
<node id='-166' action='modify' visible='true' lat='-0.00951758843' lon='0.00485156509'>
|
||||
<tag k='test:id' v='inner-S' />
|
||||
<tag k='test:section' v='way-area-with-center' />
|
||||
</node>
|
||||
<node id='-137' action='modify' visible='true' lat='-0.00215326117' lon='0.00501050741' />
|
||||
<node id='-135' action='modify' visible='true' lat='-0.00257710735' lon='0.00644098825' />
|
||||
<node id='-133' action='modify' visible='true' lat='-0.00400758819' lon='0.00750060369' />
|
||||
<node id='-131' action='modify' visible='true' lat='-0.00591489597' lon='0.00336810348' />
|
||||
<node id='-129' action='modify' visible='true' lat='-0.00766326144' lon='0.00516944972' />
|
||||
<node id='-127' action='modify' visible='true' lat='-0.00649768446' lon='0.00612310362' />
|
||||
<node id='-125' action='modify' visible='true' lat='-0.00496124208' lon='0.00686483443' />
|
||||
<node id='-123' action='modify' visible='true' lat='-0.00665662678' lon='0.00771252678' />
|
||||
<node id='-121' action='modify' visible='true' lat='-0.0099414346' lon='0.0065469498' />
|
||||
<node id='-119' action='modify' visible='true' lat='-0.01094806925' lon='0.0038979112' />
|
||||
<node id='-117' action='modify' visible='true' lat='-0.01057720386' lon='0.00267935344' />
|
||||
<node id='-115' action='modify' visible='true' lat='-0.00999441537' lon='0.00220252649' />
|
||||
<node id='-113' action='modify' visible='true' lat='-0.00919970381' lon='0.00262637267' />
|
||||
<node id='-111' action='modify' visible='true' lat='-0.00803412684' lon='0.00262637267' />
|
||||
<node id='-109' action='modify' visible='true' lat='-0.00655066523' lon='0.00193762263' />
|
||||
<node id='-107' action='modify' visible='true' lat='-0.00729239604' lon='0.00103694951' />
|
||||
<node id='-105' action='modify' visible='true' lat='-0.00607383829' lon='0.00050714179' />
|
||||
<node id='-103' action='modify' visible='true' lat='-0.00564999211' lon='0.00177868032' />
|
||||
<node id='-101' action='modify' visible='true' lat='-0.00421951128' lon='0.00050714179' />
|
||||
<node id='-99' action='modify' visible='true' lat='-0.00257710735' lon='0.00056012256' />
|
||||
<node id='-98' action='modify' visible='true' lat='-0.00151749191' lon='0.00130185337' />
|
||||
<node id='100' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='101' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='102' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.001' />
|
||||
<node id='103' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.001' />
|
||||
<node id='200' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='201' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='202' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.005' />
|
||||
<node id='203' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.005' />
|
||||
<node id='300' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='301' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='302' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.01' />
|
||||
<node id='303' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.01' />
|
||||
<node id='400' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='401' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='402' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.05' />
|
||||
<node id='403' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.05' />
|
||||
<node id='500' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='501' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='502' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.1' />
|
||||
<node id='503' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.1' />
|
||||
<node id='600' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='601' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.0' />
|
||||
<node id='602' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.1' lon='0.5' />
|
||||
<node id='603' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.5' />
|
||||
<node id='700' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='701' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.0' />
|
||||
<node id='702' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.1' />
|
||||
<node id='703' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.1' />
|
||||
<node id='800' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='801' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.0' />
|
||||
<node id='802' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.5' />
|
||||
<node id='803' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.5' />
|
||||
<node id='900' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='901' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.0' />
|
||||
<node id='902' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='1.0' />
|
||||
<node id='903' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='1.0' />
|
||||
<node id='1000' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='1001' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.0' />
|
||||
<node id='1002' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='2.0' />
|
||||
<node id='1003' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='2.0' />
|
||||
<node id='1100' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='0.0' />
|
||||
<node id='1101' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='0.0' />
|
||||
<node id='1102' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='1.0' lon='5.0' />
|
||||
<node id='1103' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='0.0' lon='5.0' />
|
||||
<way id='-100' action='modify' visible='true'>
|
||||
<nd ref='-98' />
|
||||
<nd ref='-99' />
|
||||
<nd ref='-101' />
|
||||
<nd ref='-103' />
|
||||
<nd ref='-105' />
|
||||
<nd ref='-107' />
|
||||
<nd ref='-109' />
|
||||
<nd ref='-111' />
|
||||
<nd ref='-113' />
|
||||
<nd ref='-115' />
|
||||
<nd ref='-117' />
|
||||
<nd ref='-119' />
|
||||
<nd ref='-121' />
|
||||
<nd ref='-123' />
|
||||
<nd ref='-125' />
|
||||
<nd ref='-127' />
|
||||
<nd ref='-129' />
|
||||
<nd ref='-131' />
|
||||
<nd ref='-133' />
|
||||
<nd ref='-135' />
|
||||
<nd ref='-137' />
|
||||
<nd ref='-98' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='area' />
|
||||
<tag k='test:section' v='way-area-with-center' />
|
||||
</way>
|
||||
<way id='100' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='100' />
|
||||
<nd ref='101' />
|
||||
<nd ref='102' />
|
||||
<nd ref='103' />
|
||||
<nd ref='100' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.0001' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='200' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='200' />
|
||||
<nd ref='201' />
|
||||
<nd ref='202' />
|
||||
<nd ref='203' />
|
||||
<nd ref='200' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.0005' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='300' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='300' />
|
||||
<nd ref='301' />
|
||||
<nd ref='302' />
|
||||
<nd ref='303' />
|
||||
<nd ref='300' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.001' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='400' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='400' />
|
||||
<nd ref='401' />
|
||||
<nd ref='402' />
|
||||
<nd ref='403' />
|
||||
<nd ref='400' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.005' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='500' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='500' />
|
||||
<nd ref='501' />
|
||||
<nd ref='502' />
|
||||
<nd ref='503' />
|
||||
<nd ref='500' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.01' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='600' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='600' />
|
||||
<nd ref='601' />
|
||||
<nd ref='602' />
|
||||
<nd ref='603' />
|
||||
<nd ref='600' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.05' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='700' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='700' />
|
||||
<nd ref='701' />
|
||||
<nd ref='702' />
|
||||
<nd ref='703' />
|
||||
<nd ref='700' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.1' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='800' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='800' />
|
||||
<nd ref='801' />
|
||||
<nd ref='802' />
|
||||
<nd ref='803' />
|
||||
<nd ref='800' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='0.5' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='900' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='900' />
|
||||
<nd ref='901' />
|
||||
<nd ref='902' />
|
||||
<nd ref='903' />
|
||||
<nd ref='900' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='1.0' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='1000' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='1000' />
|
||||
<nd ref='1001' />
|
||||
<nd ref='1002' />
|
||||
<nd ref='1003' />
|
||||
<nd ref='1000' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='2.0' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
<way id='1100' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='1100' />
|
||||
<nd ref='1101' />
|
||||
<nd ref='1102' />
|
||||
<nd ref='1103' />
|
||||
<nd ref='1100' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='5.0' />
|
||||
<tag k='test:section' v='poly-area' />
|
||||
</way>
|
||||
</osm>
|
||||
|
||||
@@ -1,294 +1,347 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osm version='0.6' upload='false' generator='JOSM'>
|
||||
<node id='-204' action='modify' visible='true' lat='2.000651586300547' lon='1.005746444902722'>
|
||||
<node id='-197' action='modify' visible='true' lat='2.0006515863' lon='1.0057464449'>
|
||||
<tag k='name' v='split-road' />
|
||||
</node>
|
||||
<node id='-189' action='modify' visible='true' lat='2.0005350827634585' lon='1.0057490943252971' />
|
||||
<node id='-187' action='modify' visible='true' lat='2.0005430261867043' lon='1.0058974619895207' />
|
||||
<node id='-185' action='modify' visible='true' lat='2.0005430261867043' lon='1.0060511284988949' />
|
||||
<node id='-183' action='modify' visible='true' lat='2.0005324349557014' lon='1.0061306111761574' />
|
||||
<node id='-174' action='modify' visible='true' lat='2.0005244915324045' lon='1.00551064629351' />
|
||||
<node id='-172' action='modify' visible='true' lat='2.0005668564562127' lon='1.0056086749288005' />
|
||||
<node id='-170' action='modify' visible='true' lat='2.000561560840796' lon='1.0056855081834875' />
|
||||
<node id='-168' action='modify' visible='true' lat='2.0005006612622807' lon='1.0057358472124205' />
|
||||
<node id='-166' action='modify' visible='true' lat='2.000505956877894' lon='1.0059107091023978' />
|
||||
<node id='-164' action='modify' visible='true' lat='2.0005112524934896' lon='1.0060537779214704' />
|
||||
<node id='-162' action='modify' visible='true' lat='2.0004953656466506' lon='1.006135910021308' />
|
||||
<node id='-160' action='modify' visible='true' lat='2.000513900301281' lon='1.0062842776855314' />
|
||||
<node id='-158' action='modify' visible='true' lat='2.000471535376104' lon='1.0063717086305204' />
|
||||
<node id='-156' action='modify' visible='true' lat='2.000296780048186' lon='1.0063584615176433' />
|
||||
<node id='-154' action='modify' visible='true' lat='2.000262358542008' lon='1.006281628262956' />
|
||||
<node id='-152' action='modify' visible='true' lat='2.000339144977876' lon='1.0061994961631182' />
|
||||
<node id='-150' action='modify' visible='true' lat='2.0003576796342712' lon='1.0061041169504032' />
|
||||
<node id='-148' action='modify' visible='true' lat='2.0003497362101275' lon='1.0060034388925374' />
|
||||
<node id='-146' action='modify' visible='true' lat='2.000325905937466' lon='1.0058868642992191' />
|
||||
<node id='-144' action='modify' visible='true' lat='2.000280893199271' lon='1.0057941345090795' />
|
||||
<node id='-142' action='modify' visible='true' lat='2.0002782453911037' lon='1.0056351691545544' />
|
||||
<node id='-141' action='modify' visible='true' lat='2.0003603274423103' lon='1.005470904954879' />
|
||||
<node id='-139' action='modify' visible='true' lat='2.0007265421773432' lon='1.0047054313390744'>
|
||||
<node id='-195' action='modify' visible='true' lat='2.00053508276' lon='1.00574909433' />
|
||||
<node id='-193' action='modify' visible='true' lat='2.00054302619' lon='1.00589746199' />
|
||||
<node id='-191' action='modify' visible='true' lat='2.00054302619' lon='1.0060511285' />
|
||||
<node id='-189' action='modify' visible='true' lat='2.00053243496' lon='1.00613061118' />
|
||||
<node id='-187' action='modify' visible='true' lat='2.00052449153' lon='1.00551064629' />
|
||||
<node id='-185' action='modify' visible='true' lat='2.00056685646' lon='1.00560867493' />
|
||||
<node id='-183' action='modify' visible='true' lat='2.00056156084' lon='1.00568550818' />
|
||||
<node id='-181' action='modify' visible='true' lat='2.00050066126' lon='1.00573584721' />
|
||||
<node id='-179' action='modify' visible='true' lat='2.00050595688' lon='1.0059107091' />
|
||||
<node id='-177' action='modify' visible='true' lat='2.00051125249' lon='1.00605377792' />
|
||||
<node id='-175' action='modify' visible='true' lat='2.00049536565' lon='1.00613591002' />
|
||||
<node id='-173' action='modify' visible='true' lat='2.0005139003' lon='1.00628427769' />
|
||||
<node id='-171' action='modify' visible='true' lat='2.00047153538' lon='1.00637170863' />
|
||||
<node id='-169' action='modify' visible='true' lat='2.00029678005' lon='1.00635846152' />
|
||||
<node id='-167' action='modify' visible='true' lat='2.00026235854' lon='1.00628162826' />
|
||||
<node id='-165' action='modify' visible='true' lat='2.00033914498' lon='1.00619949616' />
|
||||
<node id='-163' action='modify' visible='true' lat='2.00035767963' lon='1.00610411695' />
|
||||
<node id='-161' action='modify' visible='true' lat='2.00034973621' lon='1.00600343889' />
|
||||
<node id='-159' action='modify' visible='true' lat='2.00032590594' lon='1.0058868643' />
|
||||
<node id='-157' action='modify' visible='true' lat='2.0002808932' lon='1.00579413451' />
|
||||
<node id='-155' action='modify' visible='true' lat='2.00027824539' lon='1.00563516915' />
|
||||
<node id='-153' action='modify' visible='true' lat='2.00036032744' lon='1.00547090495' />
|
||||
<node id='-151' action='modify' visible='true' lat='2.00072654218' lon='1.00470543134'>
|
||||
<tag k='name' v='points-on-road' />
|
||||
</node>
|
||||
<node id='-112' action='modify' visible='true' lat='2.0005155253763816' lon='1.0049220138358423' />
|
||||
<node id='-110' action='modify' visible='true' lat='2.0005155253763816' lon='1.0049220138358423'>
|
||||
<node id='-149' action='modify' visible='true' lat='2.00051552538' lon='1.00492201384' />
|
||||
<node id='-147' action='modify' visible='true' lat='2.00051552538' lon='1.00492201384'>
|
||||
<tag k='test:id' v='n-N-unglued' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-108' action='modify' visible='true' lat='2.0002948553437463' lon='1.0046258759080025'>
|
||||
<node id='-145' action='modify' visible='true' lat='2.00029485534' lon='1.00462587591'>
|
||||
<tag k='test:id' v='n-S-unglued' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-106' action='modify' visible='true' lat='2.0002948553437463' lon='1.0046258759080025' />
|
||||
<node id='-104' action='modify' visible='true' lat='2.0006117740392657' lon='1.0050661381425037'>
|
||||
<node id='-143' action='modify' visible='true' lat='2.00029485534' lon='1.00462587591' />
|
||||
<node id='-141' action='modify' visible='true' lat='2.00061177404' lon='1.00506613814'>
|
||||
<tag k='test:id' v='n-NE' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-102' action='modify' visible='true' lat='2.000334854794143' lon='1.0051338707939657'>
|
||||
<node id='-139' action='modify' visible='true' lat='2.00033485479' lon='1.00513387079'>
|
||||
<tag k='test:id' v='n-SE' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-100' action='modify' visible='true' lat='2.0006240815601832' lon='1.0053155174501582' />
|
||||
<node id='-98' action='modify' visible='true' lat='2.0004086999307416' lon='1.0047582624540412'>
|
||||
<node id='-137' action='modify' visible='true' lat='2.00062408156' lon='1.00531551745' />
|
||||
<node id='-135' action='modify' visible='true' lat='2.00040869993' lon='1.00475826245'>
|
||||
<tag k='test:id' v='n-NW' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-96' action='modify' visible='true' lat='2.0003840848855767' lon='1.0046258759080025' />
|
||||
<node id='-94' action='modify' visible='true' lat='2.0004302380949586' lon='1.004499646875733' />
|
||||
<node id='-92' action='modify' visible='true' lat='2.0003687004821606' lon='1.0053278324776966' />
|
||||
<node id='-90' action='modify' visible='true' lat='2.0002640865351053' lon='1.0049368303533495' />
|
||||
<node id='-88' action='modify' visible='true' lat='2.000291778462916' lon='1.004825995105503' />
|
||||
<node id='-86' action='modify' visible='true' lat='2.0003563929593238' lon='1.004727474885195'>
|
||||
<node id='-133' action='modify' visible='true' lat='2.00038408489' lon='1.00462587591' />
|
||||
<node id='-131' action='modify' visible='true' lat='2.00043023809' lon='1.00449964688' />
|
||||
<node id='-129' action='modify' visible='true' lat='2.00036870048' lon='1.00532783248' />
|
||||
<node id='-127' action='modify' visible='true' lat='2.00026408654' lon='1.00493683035' />
|
||||
<node id='-125' action='modify' visible='true' lat='2.00029177846' lon='1.00482599511' />
|
||||
<node id='-123' action='modify' visible='true' lat='2.00035639296' lon='1.00472747489'>
|
||||
<tag k='test:id' v='n-SW' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</node>
|
||||
<node id='-84' action='modify' visible='true' lat='2.0002240870829975' lon='1.00452427693081' />
|
||||
<node id='-82' action='modify' visible='true' lat='2.000715618411992' lon='1.0018322734314236'>
|
||||
<node id='-121' action='modify' visible='true' lat='2.00022408708' lon='1.00452427693' />
|
||||
<node id='-119' action='modify' visible='true' lat='2.00071561841' lon='1.00183227343'>
|
||||
<tag k='name' v='road-with-alley' />
|
||||
</node>
|
||||
<node id='-80' action='modify' visible='true' lat='2.0007286441385155' lon='1.0004669962874884'>
|
||||
<node id='-117' action='modify' visible='true' lat='2.00072864414' lon='1.00046699629'>
|
||||
<tag k='name' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-78' action='modify' visible='true' lat='2.000354154459697' lon='1.002448114434296'>
|
||||
<node id='-115' action='modify' visible='true' lat='2.00035415446' lon='1.00244811443'>
|
||||
<tag k='test:id' v='n-main-east' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</node>
|
||||
<node id='-76' action='modify' visible='true' lat='2.000266230783582' lon='1.0015520494830263'>
|
||||
<node id='-113' action='modify' visible='true' lat='2.00026623078' lon='1.00155204948'>
|
||||
<tag k='test:id' v='n-main-west' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</node>
|
||||
<node id='-74' action='modify' visible='true' lat='2.000546283957771' lon='1.0019235091355527'>
|
||||
<node id='-111' action='modify' visible='true' lat='2.00054628396' lon='1.00192350914'>
|
||||
<tag k='test:id' v='n-alley' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</node>
|
||||
<node id='-72' action='modify' visible='true' lat='2.000354154459697' lon='1.0019235091355527'>
|
||||
<node id='-109' action='modify' visible='true' lat='2.00035415446' lon='1.00192350914'>
|
||||
<tag k='test:id' v='n-corner' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</node>
|
||||
<node id='-70' action='modify' visible='true' lat='2.0005755918453296' lon='1.0019593517336036' />
|
||||
<node id='-68' action='modify' visible='true' lat='2.000298795108618' lon='1.0026077769165225' />
|
||||
<node id='-66' action='modify' visible='true' lat='2.000311820838452' lon='1.0023699124021854' />
|
||||
<node id='-64' action='modify' visible='true' lat='2.0003150772708946' lon='1.0021255310518389' />
|
||||
<node id='-62' action='modify' visible='true' lat='2.0003085644060037' lon='1.0019593517336036' />
|
||||
<node id='-60' action='modify' visible='true' lat='2.000305307973548' lon='1.0016758693672019' />
|
||||
<node id='-58' action='modify' visible='true' lat='2.000311820838452' lon='1.0013435107307307' />
|
||||
<node id='-56' action='modify' visible='true' lat='2.0004054696330322' lon='1.0001173628501097'>
|
||||
<node id='-107' action='modify' visible='true' lat='2.00057559185' lon='1.00195935173' />
|
||||
<node id='-105' action='modify' visible='true' lat='2.00029879511' lon='1.00260777692' />
|
||||
<node id='-103' action='modify' visible='true' lat='2.00031182084' lon='1.0023699124' />
|
||||
<node id='-101' action='modify' visible='true' lat='2.00031507727' lon='1.00212553105' />
|
||||
<node id='-99' action='modify' visible='true' lat='2.00030856441' lon='1.00195935173' />
|
||||
<node id='-97' action='modify' visible='true' lat='2.00030530797' lon='1.00167586937' />
|
||||
<node id='-95' action='modify' visible='true' lat='2.00031182084' lon='1.00134351073' />
|
||||
<node id='-93' action='modify' visible='true' lat='2.00040546963' lon='1.00011736285'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-54' action='modify' visible='true' lat='2.000397598928471' lon='1.0004297578433892'>
|
||||
<node id='-91' action='modify' visible='true' lat='2.00039759893' lon='1.00042975784'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-52' action='modify' visible='true' lat='2.0004579409958114' lon='1.0006607726283354'>
|
||||
<node id='-89' action='modify' visible='true' lat='2.000457941' lon='1.00066077263'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-50' action='modify' visible='true' lat='2.0005418951727663' lon='1.0010624233339804'>
|
||||
<node id='-87' action='modify' visible='true' lat='2.00054189517' lon='1.00106242333'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-48' action='modify' visible='true' lat='2.000190337028091' lon='1.0001383641941959'>
|
||||
<node id='-85' action='modify' visible='true' lat='2.00019033703' lon='1.00013836419'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-46' action='modify' visible='true' lat='2.000198207733647' lon='1.000721151492583'>
|
||||
<node id='-83' action='modify' visible='true' lat='2.00019820773' lon='1.00072115149'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-44' action='modify' visible='true' lat='2.000219196281612' lon='1.0010676736700022'>
|
||||
<node id='-81' action='modify' visible='true' lat='2.00021919628' lon='1.00106767367'>
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-42' action='modify' visible='true' lat='2.000339880427198' lon='1.000390380323228'>
|
||||
<node id='-79' action='modify' visible='true' lat='2.00033988043' lon='1.00039038032'>
|
||||
<tag k='test:id' v='p-N2' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-40' action='modify' visible='true' lat='2.000292656197374' lon='1.0008104072049482'>
|
||||
<node id='-77' action='modify' visible='true' lat='2.0002926562' lon='1.0008104072'>
|
||||
<tag k='test:id' v='p-S1' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-38' action='modify' visible='true' lat='2.0005287773329004' lon='1.0005321393958087'>
|
||||
<node id='-75' action='modify' visible='true' lat='2.00052877733' lon='1.0005321394'>
|
||||
<tag k='test:id' v='p-N1' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-36' action='modify' visible='true' lat='2.000106382833144' lon='1.0006397712842492'>
|
||||
<node id='-73' action='modify' visible='true' lat='2.00010638283' lon='1.00063977128'>
|
||||
<tag k='test:id' v='p-S2' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</node>
|
||||
<node id='-34' action='modify' visible='true' lat='2.0007211692424525' lon='1.0035828658185688'>
|
||||
<node id='-71' action='modify' visible='true' lat='2.00072116924' lon='1.00358286582'>
|
||||
<tag k='name' v='building-on-street-corner' />
|
||||
</node>
|
||||
<node id='-32' action='modify' visible='true' lat='2.000231635335803' lon='1.0031759205058477' />
|
||||
<node id='-30' action='modify' visible='true' lat='2.000221087674047' lon='1.0040360790429201' />
|
||||
<node id='-28' action='modify' visible='true' lat='2.0002263615049336' lon='1.0042735461237067' />
|
||||
<node id='-26' action='modify' visible='true' lat='2.000105063390253' lon='1.0040413560891597' />
|
||||
<node id='-24' action='modify' visible='true' lat='2.0006377202618473' lon='1.0040363991494512' />
|
||||
<node id='-22' action='modify' visible='true' lat='2.0004388569487612' lon='1.0039042871025967' />
|
||||
<node id='-20' action='modify' visible='true' lat='2.0004385547672516' lon='1.0040022536164286' />
|
||||
<node id='-18' action='modify' visible='true' lat='2.0002343878022306' lon='1.0040016230872442' />
|
||||
<node id='-16' action='modify' visible='true' lat='2.000234689983778' lon='1.0039036565734125' />
|
||||
<node id='-14' action='modify' visible='true' lat='2.0003240388594246' lon='1.0040018999567464'>
|
||||
<node id='-69' action='modify' visible='true' lat='2.00023163534' lon='1.00317592051' />
|
||||
<node id='-67' action='modify' visible='true' lat='2.00022108767' lon='1.00403607904' />
|
||||
<node id='-65' action='modify' visible='true' lat='2.0002263615' lon='1.00427354612' />
|
||||
<node id='-63' action='modify' visible='true' lat='2.00010506339' lon='1.00404135609' />
|
||||
<node id='-61' action='modify' visible='true' lat='2.00063772026' lon='1.00403639915' />
|
||||
<node id='-59' action='modify' visible='true' lat='2.00043885695' lon='1.0039042871' />
|
||||
<node id='-57' action='modify' visible='true' lat='2.00043855477' lon='1.00400225362' />
|
||||
<node id='-55' action='modify' visible='true' lat='2.0002343878' lon='1.00400162309' />
|
||||
<node id='-53' action='modify' visible='true' lat='2.00023468998' lon='1.00390365657' />
|
||||
<node id='-51' action='modify' visible='true' lat='2.00032403886' lon='1.00400189996'>
|
||||
<tag k='test:id' v='n-edge-NS' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</node>
|
||||
<node id='-12' action='modify' visible='true' lat='2.000354798021768' lon='1.0039384858598128'>
|
||||
<node id='-49' action='modify' visible='true' lat='2.00035479802' lon='1.00393848586'>
|
||||
<tag k='test:id' v='n-inner' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</node>
|
||||
<node id='-10' action='modify' visible='true' lat='2.0004676051467527' lon='1.0039478144477645'>
|
||||
<node id='-47' action='modify' visible='true' lat='2.00046760515' lon='1.00394781445'>
|
||||
<tag k='test:id' v='n-outer' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</node>
|
||||
<node id='-8' action='modify' visible='true' lat='2.000234516370527' lon='1.0039599415620857'>
|
||||
<node id='-45' action='modify' visible='true' lat='2.00023451637' lon='1.00395994156'>
|
||||
<tag k='test:id' v='n-edge-WE' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</node>
|
||||
<node id='-43' action='modify' visible='true' lat='2.0001892102' lon='1.00653236169' />
|
||||
<node id='-41' action='modify' visible='true' lat='2.00027856164' lon='1.00667595302' />
|
||||
<node id='-39' action='modify' visible='true' lat='2.00027856164' lon='1.00681954435' />
|
||||
<node id='-37' action='modify' visible='true' lat='2.00025148545' lon='1.00691707809' />
|
||||
<node id='-35' action='modify' visible='true' lat='2.0001892102' lon='1.00704170453' />
|
||||
<node id='-33' action='modify' visible='true' lat='2.00017296448' lon='1.00724219054' />
|
||||
<node id='-31' action='modify' visible='true' lat='2.00062243814' lon='1.00685396461'>
|
||||
<tag k='name' v='parallel-road' />
|
||||
</node>
|
||||
<node id='-29' action='modify' visible='true' lat='2.00033813812' lon='1.00653156143'>
|
||||
<tag k='test:id' v='n-middle-w' />
|
||||
<tag k='test:section' v='parallel-road' />
|
||||
</node>
|
||||
<node id='-27' action='modify' visible='true' lat='2.00042478194' lon='1.00668598984' />
|
||||
<node id='-25' action='modify' visible='true' lat='2.00041665908' lon='1.00690002221' />
|
||||
<node id='-23' action='modify' visible='true' lat='2.00034084574' lon='1.00723597174'>
|
||||
<tag k='test:id' v='n-middle-e' />
|
||||
<tag k='test:section' v='parallel-road' />
|
||||
</node>
|
||||
<node id='-21' action='modify' visible='true' lat='2.00041801289' lon='1.00653968924' />
|
||||
<node id='-19' action='modify' visible='true' lat='2.00050736432' lon='1.00668328057' />
|
||||
<node id='-17' action='modify' visible='true' lat='2.00050736432' lon='1.00682687191' />
|
||||
<node id='-15' action='modify' visible='true' lat='2.00048028813' lon='1.00692440564' />
|
||||
<node id='-13' action='modify' visible='true' lat='2.00041801289' lon='1.00704903208' />
|
||||
<node id='-11' action='modify' visible='true' lat='2.00040176717' lon='1.00724951809' />
|
||||
<node id='100000' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='2.0' lon='1.0' />
|
||||
<node id='100001' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='3.0' lon='1.0' />
|
||||
<node id='100002' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='3.0' lon='2.0' />
|
||||
<node id='100003' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1' lat='2.0' lon='2.0' />
|
||||
<way id='-195' action='modify' visible='true'>
|
||||
<nd ref='-170' />
|
||||
<nd ref='-172' />
|
||||
<nd ref='-174' />
|
||||
<tag k='test:id' v='w-5' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-194' action='modify' visible='true'>
|
||||
<nd ref='-160' />
|
||||
<nd ref='-162' />
|
||||
<nd ref='-164' />
|
||||
<nd ref='-166' />
|
||||
<nd ref='-168' />
|
||||
<nd ref='-170' />
|
||||
<tag k='test:id' v='w-4a' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-193' action='modify' visible='true'>
|
||||
<nd ref='-152' />
|
||||
<nd ref='-154' />
|
||||
<nd ref='-156' />
|
||||
<nd ref='-158' />
|
||||
<nd ref='-160' />
|
||||
<tag k='test:id' v='w-3' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-192' action='modify' visible='true'>
|
||||
<nd ref='-144' />
|
||||
<nd ref='-146' />
|
||||
<nd ref='-148' />
|
||||
<nd ref='-150' />
|
||||
<nd ref='-152' />
|
||||
<tag k='test:id' v='w-2' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-184' action='modify' visible='true'>
|
||||
<nd ref='-160' />
|
||||
<way id='-237' action='modify' visible='true'>
|
||||
<nd ref='-183' />
|
||||
<nd ref='-185' />
|
||||
<nd ref='-187' />
|
||||
<tag k='test:id' v='w-5' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-235' action='modify' visible='true'>
|
||||
<nd ref='-173' />
|
||||
<nd ref='-175' />
|
||||
<nd ref='-177' />
|
||||
<nd ref='-179' />
|
||||
<nd ref='-181' />
|
||||
<nd ref='-183' />
|
||||
<tag k='test:id' v='w-4a' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-233' action='modify' visible='true'>
|
||||
<nd ref='-165' />
|
||||
<nd ref='-167' />
|
||||
<nd ref='-169' />
|
||||
<nd ref='-171' />
|
||||
<nd ref='-173' />
|
||||
<tag k='test:id' v='w-3' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-231' action='modify' visible='true'>
|
||||
<nd ref='-157' />
|
||||
<nd ref='-159' />
|
||||
<nd ref='-161' />
|
||||
<nd ref='-163' />
|
||||
<nd ref='-165' />
|
||||
<tag k='test:id' v='w-2' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-229' action='modify' visible='true'>
|
||||
<nd ref='-173' />
|
||||
<nd ref='-189' />
|
||||
<nd ref='-170' />
|
||||
<nd ref='-191' />
|
||||
<nd ref='-193' />
|
||||
<nd ref='-195' />
|
||||
<nd ref='-183' />
|
||||
<tag k='test:id' v='w-4b' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-143' action='modify' visible='true'>
|
||||
<nd ref='-141' />
|
||||
<nd ref='-142' />
|
||||
<nd ref='-144' />
|
||||
<way id='-227' action='modify' visible='true'>
|
||||
<nd ref='-153' />
|
||||
<nd ref='-155' />
|
||||
<nd ref='-157' />
|
||||
<tag k='test:id' v='w-1' />
|
||||
<tag k='test:section' v='split-road' />
|
||||
</way>
|
||||
<way id='-134' action='modify' visible='true'>
|
||||
<nd ref='-94' />
|
||||
<nd ref='-96' />
|
||||
<nd ref='-98' />
|
||||
<nd ref='-112' />
|
||||
<nd ref='-104' />
|
||||
<nd ref='-100' />
|
||||
<way id='-225' action='modify' visible='true'>
|
||||
<nd ref='-131' />
|
||||
<nd ref='-133' />
|
||||
<nd ref='-135' />
|
||||
<nd ref='-149' />
|
||||
<nd ref='-141' />
|
||||
<nd ref='-137' />
|
||||
<tag k='test:id' v='w-north' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</way>
|
||||
<way id='-132' action='modify' visible='true'>
|
||||
<nd ref='-84' />
|
||||
<nd ref='-106' />
|
||||
<nd ref='-86' />
|
||||
<nd ref='-88' />
|
||||
<nd ref='-90' />
|
||||
<nd ref='-102' />
|
||||
<nd ref='-92' />
|
||||
<way id='-223' action='modify' visible='true'>
|
||||
<nd ref='-121' />
|
||||
<nd ref='-143' />
|
||||
<nd ref='-123' />
|
||||
<nd ref='-125' />
|
||||
<nd ref='-127' />
|
||||
<nd ref='-139' />
|
||||
<nd ref='-129' />
|
||||
<tag k='test:id' v='w-south' />
|
||||
<tag k='test:section' v='points-on-roads' />
|
||||
</way>
|
||||
<way id='-130' action='modify' visible='true'>
|
||||
<nd ref='-62' />
|
||||
<nd ref='-70' />
|
||||
<way id='-221' action='modify' visible='true'>
|
||||
<nd ref='-99' />
|
||||
<nd ref='-107' />
|
||||
<tag k='test:id' v='w-alley' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</way>
|
||||
<way id='-128' action='modify' visible='true'>
|
||||
<nd ref='-58' />
|
||||
<nd ref='-60' />
|
||||
<nd ref='-62' />
|
||||
<nd ref='-64' />
|
||||
<nd ref='-66' />
|
||||
<nd ref='-68' />
|
||||
<way id='-219' action='modify' visible='true'>
|
||||
<nd ref='-95' />
|
||||
<nd ref='-97' />
|
||||
<nd ref='-99' />
|
||||
<nd ref='-101' />
|
||||
<nd ref='-103' />
|
||||
<nd ref='-105' />
|
||||
<tag k='test:id' v='w-main' />
|
||||
<tag k='test:section' v='road-with-alley' />
|
||||
</way>
|
||||
<way id='-126' action='modify' visible='true'>
|
||||
<nd ref='-56' />
|
||||
<nd ref='-54' />
|
||||
<nd ref='-52' />
|
||||
<nd ref='-50' />
|
||||
<way id='-217' action='modify' visible='true'>
|
||||
<nd ref='-93' />
|
||||
<nd ref='-91' />
|
||||
<nd ref='-89' />
|
||||
<nd ref='-87' />
|
||||
<tag k='test:id' v='w-north' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</way>
|
||||
<way id='-124' action='modify' visible='true'>
|
||||
<nd ref='-48' />
|
||||
<nd ref='-46' />
|
||||
<nd ref='-44' />
|
||||
<way id='-215' action='modify' visible='true'>
|
||||
<nd ref='-85' />
|
||||
<nd ref='-83' />
|
||||
<nd ref='-81' />
|
||||
<tag k='test:id' v='w-south' />
|
||||
<tag k='test:section' v='roads-with-pois' />
|
||||
</way>
|
||||
<way id='-122' action='modify' visible='true'>
|
||||
<nd ref='-32' />
|
||||
<nd ref='-30' />
|
||||
<nd ref='-28' />
|
||||
<way id='-213' action='modify' visible='true'>
|
||||
<nd ref='-69' />
|
||||
<nd ref='-67' />
|
||||
<nd ref='-65' />
|
||||
<tag k='test:id' v='w-WE' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</way>
|
||||
<way id='-120' action='modify' visible='true'>
|
||||
<nd ref='-26' />
|
||||
<nd ref='-30' />
|
||||
<nd ref='-24' />
|
||||
<way id='-211' action='modify' visible='true'>
|
||||
<nd ref='-63' />
|
||||
<nd ref='-67' />
|
||||
<nd ref='-61' />
|
||||
<tag k='test:id' v='w-NS' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</way>
|
||||
<way id='-118' action='modify' visible='true'>
|
||||
<nd ref='-22' />
|
||||
<nd ref='-20' />
|
||||
<nd ref='-14' />
|
||||
<nd ref='-18' />
|
||||
<nd ref='-8' />
|
||||
<nd ref='-16' />
|
||||
<nd ref='-22' />
|
||||
<way id='-209' action='modify' visible='true'>
|
||||
<nd ref='-59' />
|
||||
<nd ref='-57' />
|
||||
<nd ref='-51' />
|
||||
<nd ref='-55' />
|
||||
<nd ref='-45' />
|
||||
<nd ref='-53' />
|
||||
<nd ref='-59' />
|
||||
<tag k='area' v='yes' />
|
||||
<tag k='test:id' v='w-building' />
|
||||
<tag k='test:section' v='building-on-street-corner' />
|
||||
</way>
|
||||
<way id='-207' action='modify' visible='true'>
|
||||
<nd ref='-43' />
|
||||
<nd ref='-41' />
|
||||
<nd ref='-39' />
|
||||
<nd ref='-37' />
|
||||
<nd ref='-35' />
|
||||
<nd ref='-33' />
|
||||
<tag k='test:id' v='w-south' />
|
||||
<tag k='test:section' v='parallel-road' />
|
||||
</way>
|
||||
<way id='-205' action='modify' visible='true'>
|
||||
<nd ref='-29' />
|
||||
<nd ref='-27' />
|
||||
<nd ref='-25' />
|
||||
<nd ref='-23' />
|
||||
<tag k='test:id' v='w-middle' />
|
||||
<tag k='test:section' v='parallel-road' />
|
||||
</way>
|
||||
<way id='-203' action='modify' visible='true'>
|
||||
<nd ref='-21' />
|
||||
<nd ref='-19' />
|
||||
<nd ref='-17' />
|
||||
<nd ref='-15' />
|
||||
<nd ref='-13' />
|
||||
<nd ref='-11' />
|
||||
<tag k='test:id' v='w-north' />
|
||||
<tag k='test:section' v='parallel-road' />
|
||||
</way>
|
||||
<way id='100000' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' visible='true' version='1' changeset='1'>
|
||||
<nd ref='100000' />
|
||||
<nd ref='100001' />
|
||||
|
||||
5
tests/scenes/data/way-area-with-center.wkt
Normal file
5
tests/scenes/data/way-area-with-center.wkt
Normal file
@@ -0,0 +1,5 @@
|
||||
inner-C | POINT(0.0035625 -0.0066188)
|
||||
outer-C | POINT(0.0041244 -0.0060007)
|
||||
inner-N | POINT(0.0018846 -0.0023652)
|
||||
inner-S | POINT(0.0048516 -0.0095176)
|
||||
area | MULTIPOLYGON(((0.0077125 -0.0066566,0.0065469 -0.0099414,0.0038979 -0.0109481,0.0026794 -0.0105772,0.0022025 -0.0099944,0.0026264 -0.0091997,0.0026264 -0.0080341,0.0019376 -0.0065507,0.0010369 -0.0072924,0.0005071 -0.0060738,0.0017787 -0.00565,0.0005071 -0.0042195,0.0005601 -0.0025771,0.0013019 -0.0015175,0.0050105 -0.0021533,0.006441 -0.0025771,0.0075006 -0.0040076,0.0033681 -0.0059149,0.0051694 -0.0076633,0.0061231 -0.0064977,0.0068648 -0.0049612,0.0077125 -0.0066566)))
|
||||
@@ -27,17 +27,35 @@ def _parse_xml():
|
||||
world.results = []
|
||||
|
||||
# results
|
||||
if page.nodeName == 'searchresults':
|
||||
if page.nodeName == 'searchresults' or page.nodeName == 'lookupresults':
|
||||
for node in page.childNodes:
|
||||
if node.nodeName != "#text":
|
||||
assert_equals(node.nodeName, 'place', msg="Unexpected element '%s'" % node.nodeName)
|
||||
newresult = OrderedDict(node.attributes.items())
|
||||
assert_not_in('address', newresult)
|
||||
assert_not_in('geokml', newresult)
|
||||
assert_not_in('extratags', newresult)
|
||||
assert_not_in('namedetails', newresult)
|
||||
address = OrderedDict()
|
||||
for sub in node.childNodes:
|
||||
if sub.nodeName == 'geokml':
|
||||
newresult['geokml'] = sub.childNodes[0].toxml()
|
||||
elif sub.nodeName == 'extratags':
|
||||
newresult['extratags'] = {}
|
||||
for tag in sub.childNodes:
|
||||
assert_equals(tag.nodeName, 'tag')
|
||||
attrs = dict(tag.attributes.items())
|
||||
assert_in('key', attrs)
|
||||
assert_in('value', attrs)
|
||||
newresult['extratags'][attrs['key']] = attrs['value']
|
||||
elif sub.nodeName == 'namedetails':
|
||||
newresult['namedetails'] = {}
|
||||
for tag in sub.childNodes:
|
||||
assert_equals(tag.nodeName, 'name')
|
||||
attrs = dict(tag.attributes.items())
|
||||
assert_in('desc', attrs)
|
||||
newresult['namedetails'][attrs['desc']] = tag.firstChild.nodeValue.strip()
|
||||
|
||||
elif sub.nodeName == '#text':
|
||||
pass
|
||||
else:
|
||||
@@ -65,6 +83,21 @@ def _parse_xml():
|
||||
for sub in node.childNodes:
|
||||
address[sub.nodeName] = sub.firstChild.nodeValue.strip()
|
||||
world.results[0]['address'] = address
|
||||
elif node.nodeName == 'extratags':
|
||||
world.results[0]['extratags'] = {}
|
||||
for tag in node.childNodes:
|
||||
assert_equals(tag.nodeName, 'tag')
|
||||
attrs = dict(tag.attributes.items())
|
||||
assert_in('key', attrs)
|
||||
assert_in('value', attrs)
|
||||
world.results[0]['extratags'][attrs['key']] = attrs['value']
|
||||
elif node.nodeName == 'namedetails':
|
||||
world.results[0]['namedetails'] = {}
|
||||
for tag in node.childNodes:
|
||||
assert_equals(tag.nodeName, 'name')
|
||||
attrs = dict(tag.attributes.items())
|
||||
assert_in('desc', attrs)
|
||||
world.results[0]['namedetails'][attrs['desc']] = tag.firstChild.nodeValue.strip()
|
||||
elif node.nodeName == "#text":
|
||||
pass
|
||||
else:
|
||||
@@ -86,12 +119,14 @@ def api_result_is_valid(step, fmt):
|
||||
if world.response_format == 'html':
|
||||
document, errors = tidy_document(world.page,
|
||||
options={'char-encoding' : 'utf8'})
|
||||
assert(len(errors) == 0), "Errors found in HTML document:\n%s" % errors
|
||||
# assert(len(errors) == 0), "Errors found in HTML document:\n%s" % errors
|
||||
world.results = document
|
||||
elif world.response_format == 'xml':
|
||||
_parse_xml()
|
||||
elif world.response_format == 'json':
|
||||
world.results = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(world.page)
|
||||
if world.request_type == 'reverse':
|
||||
world.results = (world.results,)
|
||||
else:
|
||||
assert False, "Unknown page format: %s" % (world.response_format)
|
||||
|
||||
@@ -143,6 +178,11 @@ def api_result_header_contains(step):
|
||||
assert_in(line['attr'], world.result_header)
|
||||
m = re.match("%s$" % (line['value'],), world.result_header[line['attr']])
|
||||
|
||||
@step(u'result header has no attribute (.*)')
|
||||
def api_result_header_contains_not(step, attr):
|
||||
step.given('the result is valid')
|
||||
assert_not_in(attr, world.result_header)
|
||||
|
||||
@step(u'results contain$')
|
||||
def api_result_contains(step):
|
||||
step.given('at least 1 result is returned')
|
||||
@@ -194,7 +234,10 @@ def api_result_address_exact(step, resid):
|
||||
addr = world.results[resid]['address']
|
||||
for line in step.hashes:
|
||||
assert_in(line['type'], addr)
|
||||
assert_equals(line['value'], addr[line['type']])
|
||||
m = re.match("%s$" % line['value'], addr[line['type']])
|
||||
assert_is_not_none(m, msg="field %s does not match: %s$ != %s." % (
|
||||
line['type'], line['value'], addr[line['type']]))
|
||||
#assert_equals(line['value'], addr[line['type']])
|
||||
|
||||
@step(u'address of result (\d+) does not contain (.*)')
|
||||
def api_result_address_details_missing(step, resid, types):
|
||||
|
||||
@@ -10,6 +10,7 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def api_call(requesttype):
|
||||
world.request_type = requesttype
|
||||
world.json_callback = None
|
||||
data = urllib.urlencode(world.params)
|
||||
url = "%s/%s?%s" % (world.config.base_url, requesttype, data)
|
||||
@@ -36,7 +37,7 @@ def api_call(requesttype):
|
||||
world.response_format = fmt
|
||||
elif fmt in ('json', 'jsonv2'):
|
||||
if 'json_callback' in world.params:
|
||||
world.json_callback = world.params['json_callback']
|
||||
world.json_callback = world.params['json_callback'].encode('utf8')
|
||||
assert world.page.startswith(world.json_callback + '(')
|
||||
assert world.page.endswith(')')
|
||||
world.page = world.page[(len(world.json_callback)+1):-1]
|
||||
@@ -103,6 +104,16 @@ def api_setup_reverse(step, fmt, lat, lon):
|
||||
world.params['format'] = fmt.strip()
|
||||
api_call('reverse')
|
||||
|
||||
@step(u'looking up place ([NRW]?\d+)')
|
||||
def api_setup_details_reverse(step, obj):
|
||||
if obj[0] in ('N', 'R', 'W'):
|
||||
# an osm id
|
||||
world.params['osm_type'] = obj[0]
|
||||
world.params['osm_id'] = obj[1:]
|
||||
else:
|
||||
world.params['place_id'] = obj
|
||||
api_call('reverse')
|
||||
|
||||
@step(u'looking up details for ([NRW]?\d+)')
|
||||
def api_setup_details(step, obj):
|
||||
if obj[0] in ('N', 'R', 'W'):
|
||||
@@ -112,3 +123,14 @@ def api_setup_details(step, obj):
|
||||
else:
|
||||
world.params['place_id'] = obj
|
||||
api_call('details')
|
||||
|
||||
@step(u'looking up (\w+) places ((?:[a-z]\d+,*)+)')
|
||||
def api_setup_lookup(step, fmt, ids):
|
||||
world.params['osm_ids'] = ids
|
||||
if fmt and fmt.strip():
|
||||
world.params['format'] = fmt.strip()
|
||||
api_call('lookup')
|
||||
|
||||
@step(u'sending an API call (\w+)')
|
||||
def api_general_call(step, call):
|
||||
api_call(call)
|
||||
|
||||
@@ -22,7 +22,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
@step(u'table placex contains as names for (N|R|W)(\d+)')
|
||||
def check_placex_names(step, osmtyp, osmid):
|
||||
""" Check for the exact content of the name hstaore in placex.
|
||||
""" Check for the exact content of the name hstore in placex.
|
||||
"""
|
||||
cur = world.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
cur.execute('SELECT name FROM placex where osm_type = %s and osm_id =%s', (osmtyp, int(osmid)))
|
||||
@@ -43,46 +43,55 @@ def check_placex_content(step, tablename):
|
||||
given columns are tested. If there is more than one
|
||||
line for an OSM object, they must match in these columns.
|
||||
"""
|
||||
cur = world.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
for line in step.hashes:
|
||||
osmtype, osmid, cls = world.split_id(line['object'])
|
||||
q = 'SELECT *'
|
||||
if tablename == 'placex':
|
||||
q = q + ", ST_X(centroid) as clat, ST_Y(centroid) as clon"
|
||||
q = q + ' FROM %s where osm_type = %%s and osm_id = %%s' % (tablename,)
|
||||
if cls is None:
|
||||
params = (osmtype, osmid)
|
||||
else:
|
||||
q = q + ' and class = %s'
|
||||
params = (osmtype, osmid, cls)
|
||||
cur.execute(q, params)
|
||||
assert(cur.rowcount > 0)
|
||||
for res in cur:
|
||||
for k,v in line.iteritems():
|
||||
if not k == 'object':
|
||||
assert_in(k, res)
|
||||
if type(res[k]) is dict:
|
||||
val = world.make_hash(v)
|
||||
assert_equals(res[k], val)
|
||||
elif k in ('parent_place_id', 'linked_place_id'):
|
||||
pid = world.get_placeid(v)
|
||||
assert_equals(pid, res[k], "Results for '%s'/'%s' differ: '%s' != '%s'" % (line['object'], k, pid, res[k]))
|
||||
elif k == 'centroid':
|
||||
world.match_geometry((res['clat'], res['clon']), v)
|
||||
else:
|
||||
assert_equals(str(res[k]), v, "Results for '%s'/'%s' differ: '%s' != '%s'" % (line['object'], k, str(res[k]), v))
|
||||
try:
|
||||
cur = world.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
for line in step.hashes:
|
||||
osmtype, osmid, cls = world.split_id(line['object'])
|
||||
q = 'SELECT *'
|
||||
if tablename == 'placex':
|
||||
q = q + ", ST_X(centroid) as clat, ST_Y(centroid) as clon"
|
||||
q = q + ", ST_GeometryType(geometry) as geometrytype"
|
||||
q = q + ' FROM %s where osm_type = %%s and osm_id = %%s' % (tablename,)
|
||||
if cls is None:
|
||||
params = (osmtype, osmid)
|
||||
else:
|
||||
q = q + ' and class = %s'
|
||||
params = (osmtype, osmid, cls)
|
||||
cur.execute(q, params)
|
||||
assert(cur.rowcount > 0)
|
||||
for res in cur:
|
||||
for k,v in line.iteritems():
|
||||
if not k == 'object':
|
||||
assert_in(k, res)
|
||||
if type(res[k]) is dict:
|
||||
val = world.make_hash(v)
|
||||
assert_equals(res[k], val)
|
||||
elif k in ('parent_place_id', 'linked_place_id'):
|
||||
pid = world.get_placeid(v)
|
||||
assert_equals(pid, res[k], "Results for '%s'/'%s' differ: '%s' != '%s'" % (line['object'], k, pid, res[k]))
|
||||
elif k == 'centroid':
|
||||
world.match_geometry((res['clat'], res['clon']), v)
|
||||
else:
|
||||
assert_equals(str(res[k]), v, "Results for '%s'/'%s' differ: '%s' != '%s'" % (line['object'], k, str(res[k]), v))
|
||||
finally:
|
||||
cur.close()
|
||||
world.conn.commit()
|
||||
|
||||
@step(u'table (placex?) has no entry for (N|R|W)(\d+)(:\w+)?')
|
||||
def check_placex_missing(step, tablename, osmtyp, osmid, placeclass):
|
||||
cur = world.conn.cursor()
|
||||
q = 'SELECT count(*) FROM %s where osm_type = %%s and osm_id = %%s' % (tablename, )
|
||||
args = [osmtyp, int(osmid)]
|
||||
if placeclass is not None:
|
||||
q = q + ' and class = %s'
|
||||
args.append(placeclass[1:])
|
||||
cur.execute(q, args)
|
||||
numres = cur.fetchone()[0]
|
||||
assert_equals (numres, 0)
|
||||
try:
|
||||
q = 'SELECT count(*) FROM %s where osm_type = %%s and osm_id = %%s' % (tablename, )
|
||||
args = [osmtyp, int(osmid)]
|
||||
if placeclass is not None:
|
||||
q = q + ' and class = %s'
|
||||
args.append(placeclass[1:])
|
||||
cur.execute(q, args)
|
||||
numres = cur.fetchone()[0]
|
||||
assert_equals (numres, 0)
|
||||
finally:
|
||||
cur.close()
|
||||
world.conn.commit()
|
||||
|
||||
@step(u'search_name table contains$')
|
||||
def check_search_name_content(step):
|
||||
@@ -110,6 +119,54 @@ def check_search_name_content(step):
|
||||
else:
|
||||
raise Exception("Cannot handle field %s in search_name table" % (k, ))
|
||||
|
||||
@step(u'way (\d+) expands to housenumbers')
|
||||
def check_interpolated_housenumbers(step, nodeid):
|
||||
"""Check that the exact set of housenumbers has been entered in
|
||||
placex for the given source node. Expected are two columns:
|
||||
housenumber and centroid
|
||||
"""
|
||||
numbers = {}
|
||||
for line in step.hashes:
|
||||
assert line["housenumber"] not in numbers
|
||||
numbers[line["housenumber"]] = line["centroid"]
|
||||
cur = world.conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
||||
cur.execute("""SELECT DISTINCT housenumber,
|
||||
ST_X(centroid) as clat, ST_Y(centroid) as clon
|
||||
FROM placex WHERE osm_type = 'W' and osm_id = %s
|
||||
and class = 'place' and type = 'address'""",
|
||||
(int(nodeid),))
|
||||
assert_equals(len(numbers), cur.rowcount)
|
||||
for r in cur:
|
||||
assert_in(r["housenumber"], numbers)
|
||||
world.match_geometry((r['clat'], r['clon']), numbers[r["housenumber"]])
|
||||
del numbers[r["housenumber"]]
|
||||
|
||||
@step(u'way (\d+) expands exactly to housenumbers ([0-9,]*)')
|
||||
def check_interpolated_housenumber_list(step, nodeid, numberlist):
|
||||
""" Checks that the interpolated house numbers corresponds
|
||||
to the given list.
|
||||
"""
|
||||
expected = numberlist.split(',');
|
||||
cur = world.conn.cursor()
|
||||
cur.execute("""SELECT housenumber FROM placex
|
||||
WHERE osm_type = 'W' and osm_id = %s
|
||||
and class = 'place' and type = 'address'""", (int(nodeid),))
|
||||
for r in cur:
|
||||
assert_in(r[0], expected, "Unexpected house number %s for node %s." % (r[0], nodeid))
|
||||
expected.remove(r[0])
|
||||
assert_equals(0, len(expected), "Missing house numbers for way %s: %s" % (nodeid, expected))
|
||||
|
||||
@step(u'way (\d+) expands to no housenumbers')
|
||||
def check_no_interpolated_housenumber_list(step, nodeid):
|
||||
""" Checks that the interpolated house numbers corresponds
|
||||
to the given list.
|
||||
"""
|
||||
cur = world.conn.cursor()
|
||||
cur.execute("""SELECT housenumber FROM placex
|
||||
WHERE osm_type = 'W' and osm_id = %s
|
||||
and class = 'place' and type = 'address'""", (int(nodeid),))
|
||||
res = [r[0] for r in cur]
|
||||
assert_equals(0, len(res), "Unexpected house numbers for way %s: %s" % (nodeid, res))
|
||||
|
||||
@step(u'table search_name has no entry for (.*)')
|
||||
def check_placex_missing(step, osmid):
|
||||
|
||||
@@ -95,6 +95,9 @@ def _format_placex_cols(cols, geomtype, force_name):
|
||||
else:
|
||||
coords = "'%s'::geometry" % coords.wkt
|
||||
cols['geometry'] = coords
|
||||
for k in cols:
|
||||
if not cols[k]:
|
||||
cols[k] = None
|
||||
|
||||
|
||||
def _insert_place_table_nodes(places, force_name):
|
||||
@@ -213,8 +216,8 @@ def import_database(step):
|
||||
world.run_nominatim_script('setup', 'create-functions', 'create-partition-functions')
|
||||
cur = world.conn.cursor()
|
||||
cur.execute("""insert into placex (osm_type, osm_id, class, type, name, admin_level,
|
||||
housenumber, street, addr_place, isin, postcode, country_code, extratags,
|
||||
geometry) select * from place""")
|
||||
housenumber, street, addr_place, isin, postcode, country_code, extratags,
|
||||
geometry) select * from place""")
|
||||
world.conn.commit()
|
||||
world.run_nominatim_script('setup', 'index', 'index-noanalyse')
|
||||
#world.db_dump_table('placex')
|
||||
|
||||
@@ -108,7 +108,7 @@ def _sort_xml_entries(x, y):
|
||||
|
||||
def write_osm_obj(fd, obj):
|
||||
if obj['type'] == 'N':
|
||||
fd.write('<node id="%(id)d" lat="%(lat).8f" lon="%(lon).8f" version="%(version)s" timestamp="%(timestamp)%" changeset="%(changeset)s" uid="%(uid)s" user="%(user)s"'% obj)
|
||||
fd.write('<node id="%(id)d" lat="%(lat).8f" lon="%(lon).8f" version="%(version)s" timestamp="%(timestamp)s" changeset="%(changeset)s" uid="%(uid)s" user="%(user)s"'% obj)
|
||||
if obj['tags'] is None:
|
||||
fd.write('/>\n')
|
||||
else:
|
||||
@@ -140,7 +140,7 @@ def osm2pgsql_load_place(step):
|
||||
world.osm2pgsql.sort(cmp=_sort_xml_entries)
|
||||
|
||||
# create a OSM file in /tmp
|
||||
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as fd:
|
||||
with tempfile.NamedTemporaryFile(dir='/tmp', suffix='.osm', delete=False) as fd:
|
||||
fname = fd.name
|
||||
fd.write("<?xml version='1.0' encoding='UTF-8'?>\n")
|
||||
fd.write('<osm version="0.6" generator="test-nominatim" timestamp="2014-08-26T20:22:02Z">\n')
|
||||
@@ -154,7 +154,7 @@ def osm2pgsql_load_place(step):
|
||||
logger.debug( "Filename: %s" % fname)
|
||||
|
||||
cmd = [os.path.join(world.config.source_dir, 'utils', 'setup.php')]
|
||||
cmd.extend(['--osm-file', fname, '--import-data'])
|
||||
cmd.extend(['--osm-file', fname, '--import-data','--osm2pgsql-cache', '300'])
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
(outp, outerr) = proc.communicate()
|
||||
assert (proc.returncode == 0), "OSM data import failed:\n%s\n%s\n" % (outp, outerr)
|
||||
@@ -188,7 +188,7 @@ def osm2pgsql_update_place(step):
|
||||
world.run_nominatim_script('setup', 'index', 'index-noanalyse')
|
||||
world.run_nominatim_script('setup', 'create-functions', 'create-partition-functions', 'enable-diff-updates')
|
||||
|
||||
with tempfile.NamedTemporaryFile(dir='/tmp', delete=False) as fd:
|
||||
with tempfile.NamedTemporaryFile(dir='/tmp', suffix='.osc', delete=False) as fd:
|
||||
fname = fd.name
|
||||
fd.write("<?xml version='1.0' encoding='UTF-8'?>\n")
|
||||
fd.write('<osmChange version="0.6" generator="Osmosis 0.43.1">\n')
|
||||
|
||||
@@ -27,7 +27,7 @@ class NominatimConfig:
|
||||
self.template_db = os.environ.get('TEMPLATE_DB', 'test_template_nominatim')
|
||||
self.test_db = os.environ.get('TEST_DB', 'test_nominatim')
|
||||
self.local_settings_file = os.environ.get('NOMINATIM_SETTINGS', '/tmp/nominatim_settings.php')
|
||||
self.reuse_template = 'NOMINATIM_REUSE_TEMPLATE' in os.environ
|
||||
self.reuse_template = 'NOMINATIM_REMOVE_TEMPLATE' not in os.environ
|
||||
self.keep_scenario_db = 'NOMINATIM_KEEP_SCENARIO_DB' in os.environ
|
||||
os.environ['NOMINATIM_SETTINGS'] = '/tmp/nominatim_settings.php'
|
||||
|
||||
@@ -94,7 +94,7 @@ def get_placeid(oid):
|
||||
q = 'SELECT place_id FROM placex where osm_type = %s and osm_id = %s and class = %s'
|
||||
params = (osmtype, osmid, cls)
|
||||
cur.execute(q, params)
|
||||
assert_equals (cur.rowcount, 1)
|
||||
assert_equals(cur.rowcount, 1, "%d rows found for place %s" % (cur.rowcount, oid))
|
||||
return cur.fetchone()[0]
|
||||
|
||||
|
||||
|
||||
@@ -10,95 +10,20 @@
|
||||
array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
|
||||
array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
|
||||
|
||||
array('parse-tiger', '', 0, 1, 1, 1, 'realpath', 'Convert tiger edge files to nominatim sql import'),
|
||||
array('parse-tiger-2011', '', 0, 1, 1, 1, 'realpath', 'Convert tiger edge files to nominatim sql import - datafiles from 2011 or later (source: edges directory of tiger data)'),
|
||||
array('parse-tiger', '', 0, 1, 1, 1, 'realpath', 'Convert tiger edge files to nominatim sql import - datafiles from 2011 or later (source: edges directory of tiger data)'),
|
||||
);
|
||||
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
|
||||
|
||||
$bDidSomething = false;
|
||||
|
||||
if (isset($aCMDResult['parse-tiger']))
|
||||
{
|
||||
$bDidSomething = true;
|
||||
foreach(glob($aCMDResult['parse-tiger'].'/??_*', GLOB_ONLYDIR) as $sStateFolder)
|
||||
{
|
||||
preg_match('#([0-9]{2})_(.*)#',basename($sStateFolder), $aMatch);
|
||||
var_dump($aMatch);
|
||||
exit;
|
||||
foreach(glob($sStateFolder.'/?????_*', GLOB_ONLYDIR) as $sCountyFolder)
|
||||
{
|
||||
set_time_limit(30);
|
||||
preg_match('#([0-9]{5})_(.*)#',basename($sCountyFolder), $aMatch);
|
||||
$sCountyID = $aMatch[1];
|
||||
$sCountyName = str_replace('_', ' ', $aMatch[2]);
|
||||
$sImportFile = $sCountyFolder.'/tl_2009_'.$sCountyID.'_edges.zip';
|
||||
$sCountyName = str_replace("'", "''", $sCountyName);
|
||||
$sCountyName = str_replace(" County", "", $sCountyName);
|
||||
echo "'$sCountyID' : '$sCountyName' ,\n";
|
||||
}
|
||||
}
|
||||
exit;
|
||||
|
||||
if (!file_exists(CONST_BasePath.'/data/tiger2009')) mkdir(CONST_BasePath.'/data/tiger2009');
|
||||
if (!file_exists(CONST_Tiger_Data_Path)) mkdir(CONST_Tiger_Data_Path);
|
||||
|
||||
$sTempDir = tempnam('/tmp', 'tiger');
|
||||
unlink($sTempDir);
|
||||
mkdir($sTempDir);
|
||||
|
||||
foreach(glob($aCMDResult['parse-tiger'].'/??_*', GLOB_ONLYDIR) as $sStateFolder)
|
||||
{
|
||||
foreach(glob($sStateFolder.'/?????_*', GLOB_ONLYDIR) as $sCountyFolder)
|
||||
{
|
||||
set_time_limit(30);
|
||||
preg_match('#([0-9]{5})_(.*)#',basename($sCountyFolder), $aMatch);
|
||||
$sCountyID = $aMatch[1];
|
||||
$sCountyName = str_replace('_', ' ', $aMatch[2]);
|
||||
$sImportFile = $sCountyFolder.'/tl_2009_'.$sCountyID.'_edges.zip';
|
||||
echo "$sCountyID, $sCountyName\n";
|
||||
if (!file_exists($sImportFile))
|
||||
{
|
||||
echo "Missing: $sImportFile\n";
|
||||
}
|
||||
$sUnzipCmd = "unzip -d $sTempDir $sImportFile";
|
||||
exec($sUnzipCmd);
|
||||
if (!file_exists($sTempDir.'/tl_2009_'.$sCountyID.'_edges.shp'))
|
||||
{
|
||||
echo "Failed unzip ($sCountyID)\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sParseCmd = CONST_BasePath.'/utils/tigerAddressImport.py '.$sTempDir.'/tl_2009_'.$sCountyID.'_edges.shp';
|
||||
exec($sParseCmd);
|
||||
if (!file_exists($sTempDir.'/tl_2009_'.$sCountyID.'_edges.osm1.osm'))
|
||||
{
|
||||
echo "Failed parse ($sCountyID)\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
copy($sTempDir.'/tl_2009_'.$sCountyID.'_edges.osm1.osm', CONST_BasePath.'/data/tiger2009/'.$sCountyID.'.sql');
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
foreach(glob($sTempDir.'/*') as $sTmpFile)
|
||||
{
|
||||
unlink($sTmpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isset($aCMDResult['parse-tiger-2011']))
|
||||
{
|
||||
if (!file_exists(CONST_BasePath.'/data/tiger2011')) mkdir(CONST_BasePath.'/data/tiger2011');
|
||||
|
||||
$sTempDir = tempnam('/tmp', 'tiger');
|
||||
unlink($sTempDir);
|
||||
mkdir($sTempDir);
|
||||
|
||||
|
||||
$bDidSomething = true;
|
||||
foreach(glob($aCMDResult['parse-tiger-2011'].'/tl_20??_?????_edges.zip', 0) as $sImportFile)
|
||||
foreach(glob($aCMDResult['parse-tiger'].'/tl_20??_?????_edges.zip', 0) as $sImportFile)
|
||||
{
|
||||
set_time_limit(30);
|
||||
preg_match('#([0-9]{5})_(.*)#',basename($sImportFile), $aMatch);
|
||||
@@ -122,7 +47,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
copy($sOsmFile, CONST_BasePath.'/data/tiger2011/'.$sCountyID.'.sql');
|
||||
copy($sOsmFile, CONST_Tiger_Data_Path.'/'.$sCountyID.'.sql');
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if (isset($aCMDResult['bounded'])) $aCMDResult['bounded'] = 'true';
|
||||
if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false';
|
||||
|
||||
$oGeocode =& new Geocode($oDB);
|
||||
$oGeocode = new Geocode($oDB);
|
||||
if (isset($aCMDResult['accept-language']) && $aCMDResult['accept-language'])
|
||||
$oGeocode->setLanguagePreference(getPreferredLanguages($aCMDResult['accept-language']));
|
||||
else
|
||||
|
||||
300
utils/setup.php
300
utils/setup.php
@@ -33,13 +33,13 @@
|
||||
array('disable-token-precalc', '', 0, 1, 0, 0, 'bool', 'Disable name precalculation (EXPERT)'),
|
||||
array('import-tiger-data', '', 0, 1, 0, 0, 'bool', 'Import tiger data (not included in \'all\')'),
|
||||
array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Calculate postcode centroids'),
|
||||
array('create-roads', '', 0, 1, 0, 0, 'bool', ''),
|
||||
array('osmosis-init', '', 0, 1, 0, 0, 'bool', 'Generate default osmosis configuration'),
|
||||
array('index', '', 0, 1, 0, 0, 'bool', 'Index the data'),
|
||||
array('index-noanalyse', '', 0, 1, 0, 0, 'bool', 'Do not perform analyse operations during index (EXPERT)'),
|
||||
array('index-output', '', 0, 1, 1, 1, 'string', 'File to dump index information to'),
|
||||
array('create-search-indices', '', 0, 1, 0, 0, 'bool', 'Create additional indices required for search and update'),
|
||||
array('create-website', '', 0, 1, 1, 1, 'realpath', 'Create symlinks to setup web directory'),
|
||||
array('drop', '', 0, 1, 0, 0, 'bool', 'Drop tables needed for updates, making the database readonly (EXPERIMENTAL)'),
|
||||
);
|
||||
getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
|
||||
|
||||
@@ -79,21 +79,25 @@
|
||||
}
|
||||
|
||||
// Assume we can steal all the cache memory in the box (unless told otherwise)
|
||||
$iCacheMemory = (isset($aCMDResult['osm2pgsql-cache'])?$aCMDResult['osm2pgsql-cache']:getCacheMemoryMB());
|
||||
if ($iCacheMemory > getTotalMemoryMB())
|
||||
if (isset($aCMDResult['osm2pgsql-cache']))
|
||||
{
|
||||
$iCacheMemory = $aCMDResult['osm2pgsql-cache'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCacheMemory = getCacheMemoryMB();
|
||||
echo "WARNING: resetting cache memory to $iCacheMemory\n";
|
||||
}
|
||||
|
||||
$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
|
||||
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
||||
|
||||
$fPostgisVersion = (float) CONST_Postgis_Version;
|
||||
|
||||
if ($aCMDResult['create-db'] || $aCMDResult['all'])
|
||||
{
|
||||
echo "Create DB\n";
|
||||
$bDidSomething = true;
|
||||
$oDB =& DB::connect(CONST_Database_DSN, false);
|
||||
$oDB = DB::connect(CONST_Database_DSN, false);
|
||||
if (!PEAR::isError($oDB))
|
||||
{
|
||||
fail('database already exists ('.CONST_Database_DSN.')');
|
||||
@@ -110,7 +114,7 @@
|
||||
$oDB =& getDB();
|
||||
|
||||
$sVersionString = $oDB->getOne('select version()');
|
||||
preg_match('#PostgreSQL ([0-9]+)[.]([0-9]+)[.]([0-9]+) #', $sVersionString, $aMatches);
|
||||
preg_match('#PostgreSQL ([0-9]+)[.]([0-9]+)[^0-9]#', $sVersionString, $aMatches);
|
||||
if (CONST_Postgresql_Version != $aMatches[1].'.'.$aMatches[2])
|
||||
{
|
||||
echo "ERROR: PostgreSQL version is not correct. Expected ".CONST_Postgresql_Version." found ".$aMatches[1].'.'.$aMatches[2]."\n";
|
||||
@@ -126,12 +130,11 @@
|
||||
pgsqlRunScript('CREATE EXTENSION hstore');
|
||||
}
|
||||
|
||||
$fPostgisVersion = (float) CONST_Postgis_Version;
|
||||
if ($fPostgisVersion < 2.0) {
|
||||
pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/postgis.sql');
|
||||
pgsqlRunScriptFile(CONST_Path_Postgresql_Postgis.'/spatial_ref_sys.sql');
|
||||
} else {
|
||||
pgsqlRunScript('CREATE EXTENSION postgis');
|
||||
pgsqlRunScript('CREATE EXTENSION IF NOT EXISTS postgis');
|
||||
}
|
||||
if ($fPostgisVersion < 2.1) {
|
||||
// Function was renamed in 2.1 and throws an annoying deprecation warning
|
||||
@@ -190,7 +193,15 @@
|
||||
{
|
||||
$osm2pgsql .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
|
||||
}
|
||||
$osm2pgsql .= ' -lsc -O gazetteer --hstore';
|
||||
if (CONST_Tablespace_Osm2pgsql_Data)
|
||||
$osm2pgsql .= ' --tablespace-slim-data '.CONST_Tablespace_Osm2pgsql_Data;
|
||||
if (CONST_Tablespace_Osm2pgsql_Index)
|
||||
$osm2pgsql .= ' --tablespace-slim-index '.CONST_Tablespace_Osm2pgsql_Index;
|
||||
if (CONST_Tablespace_Place_Data)
|
||||
$osm2pgsql .= ' --tablespace-main-data '.CONST_Tablespace_Place_Data;
|
||||
if (CONST_Tablespace_Place_Index)
|
||||
$osm2pgsql .= ' --tablespace-main-index '.CONST_Tablespace_Place_Index;
|
||||
$osm2pgsql .= ' -lsc -O gazetteer --hstore --number-processes 1';
|
||||
$osm2pgsql .= ' -C '.$iCacheMemory;
|
||||
$osm2pgsql .= ' -P '.$aDSNInfo['port'];
|
||||
$osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file'];
|
||||
@@ -215,6 +226,15 @@
|
||||
if ($aCMDResult['enable-debug-statements']) $sTemplate = str_replace('--DEBUG:', '', $sTemplate);
|
||||
if (CONST_Limit_Reindexing) $sTemplate = str_replace('--LIMIT INDEXING:', '', $sTemplate);
|
||||
pgsqlRunScript($sTemplate);
|
||||
|
||||
if ($fPostgisVersion < 2.0) {
|
||||
echo "Helper functions for postgis < 2.0\n";
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/postgis_15_aux.sql');
|
||||
} else {
|
||||
echo "Helper functions for postgis >= 2.0\n";
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/postgis_20_aux.sql');
|
||||
}
|
||||
pgsqlRunScript($sTemplate);
|
||||
}
|
||||
|
||||
if ($aCMDResult['create-minimal-tables'])
|
||||
@@ -249,13 +269,30 @@
|
||||
|
||||
if ($aCMDResult['create-tables'] || $aCMDResult['all'])
|
||||
{
|
||||
echo "Tables\n";
|
||||
$bDidSomething = true;
|
||||
pgsqlRunScriptFile(CONST_BasePath.'/sql/tables.sql');
|
||||
|
||||
echo "Tables\n";
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/tables.sql');
|
||||
$sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:address-data}',
|
||||
CONST_Tablespace_Address_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:address-index}',
|
||||
CONST_Tablespace_Address_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:search-data}',
|
||||
CONST_Tablespace_Search_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:search-index}',
|
||||
CONST_Tablespace_Search_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-data}',
|
||||
CONST_Tablespace_Aux_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-index}',
|
||||
CONST_Tablespace_Aux_Index, $sTemplate);
|
||||
pgsqlRunScript($sTemplate, false);
|
||||
|
||||
// re-run the functions
|
||||
echo "Functions\n";
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
|
||||
$sTemplate = str_replace('{modulepath}',CONST_BasePath.'/module', $sTemplate);
|
||||
$sTemplate = str_replace('{modulepath}',
|
||||
CONST_BasePath.'/module', $sTemplate);
|
||||
pgsqlRunScript($sTemplate);
|
||||
}
|
||||
|
||||
@@ -273,6 +310,18 @@
|
||||
if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
|
||||
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-tables.src.sql');
|
||||
$sTemplate = replace_tablespace('{ts:address-data}',
|
||||
CONST_Tablespace_Address_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:address-index}',
|
||||
CONST_Tablespace_Address_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:search-data}',
|
||||
CONST_Tablespace_Search_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:search-index}',
|
||||
CONST_Tablespace_Search_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-data}',
|
||||
CONST_Tablespace_Aux_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-index}',
|
||||
CONST_Tablespace_Aux_Index, $sTemplate);
|
||||
preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
|
||||
foreach($aMatches as $aMatch)
|
||||
{
|
||||
@@ -420,40 +469,17 @@
|
||||
pgsqlRunScript('ANALYSE');
|
||||
}
|
||||
|
||||
if ($aCMDResult['create-roads'])
|
||||
{
|
||||
$bDidSomething = true;
|
||||
|
||||
$oDB =& getDB();
|
||||
$aDBInstances = array();
|
||||
for($i = 0; $i < $iInstances; $i++)
|
||||
{
|
||||
$aDBInstances[$i] =& getDB(true);
|
||||
if (!pg_query($aDBInstances[$i]->connection, 'set enable_bitmapscan = off')) fail(pg_last_error($oDB->connection));
|
||||
$sSQL = 'select count(*) from (select insertLocationRoad(partition, place_id, calculated_country_code, geometry) from ';
|
||||
$sSQL .= 'placex where osm_id % '.$iInstances.' = '.$i.' and rank_search between 26 and 27 and class = \'highway\') as x ';
|
||||
if ($aCMDResult['verbose']) echo "$sSQL\n";
|
||||
if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
|
||||
}
|
||||
$bAnyBusy = true;
|
||||
while($bAnyBusy)
|
||||
{
|
||||
$bAnyBusy = false;
|
||||
for($i = 0; $i < $iInstances; $i++)
|
||||
{
|
||||
if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
|
||||
}
|
||||
sleep(1);
|
||||
echo '.';
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if ($aCMDResult['import-tiger-data'])
|
||||
{
|
||||
$bDidSomething = true;
|
||||
|
||||
pgsqlRunScriptFile(CONST_BasePath.'/sql/tiger_import_start.sql');
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_start.sql');
|
||||
$sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-data}',
|
||||
CONST_Tablespace_Aux_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-index}',
|
||||
CONST_Tablespace_Aux_Index, $sTemplate);
|
||||
pgsqlRunScript($sTemplate, false);
|
||||
|
||||
$aDBInstances = array();
|
||||
for($i = 0; $i < $iInstances; $i++)
|
||||
@@ -461,7 +487,7 @@
|
||||
$aDBInstances[$i] =& getDB(true);
|
||||
}
|
||||
|
||||
foreach(glob(CONST_BasePath.'/data/tiger2011/*.sql') as $sFile)
|
||||
foreach(glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile)
|
||||
{
|
||||
echo $sFile.': ';
|
||||
$hFile = fopen($sFile, "r");
|
||||
@@ -505,7 +531,13 @@
|
||||
}
|
||||
|
||||
echo "Creating indexes\n";
|
||||
pgsqlRunScriptFile(CONST_BasePath.'/sql/tiger_import_finish.sql');
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_finish.sql');
|
||||
$sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-data}',
|
||||
CONST_Tablespace_Aux_Data, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-index}',
|
||||
CONST_Tablespace_Aux_Index, $sTemplate);
|
||||
pgsqlRunScript($sTemplate, false);
|
||||
}
|
||||
|
||||
if ($aCMDResult['calculate-postcodes'] || $aCMDResult['all'])
|
||||
@@ -526,7 +558,7 @@
|
||||
if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
|
||||
}
|
||||
|
||||
if ($aCMDResult['osmosis-init'] || $aCMDResult['all'])
|
||||
if ($aCMDResult['osmosis-init'] || ($aCMDResult['all'] && !$aCMDResult['drop'])) // no use doing osmosis-init when dropping update tables
|
||||
{
|
||||
$bDidSomething = true;
|
||||
$oDB =& getDB();
|
||||
@@ -554,7 +586,7 @@
|
||||
}
|
||||
|
||||
// Find the last node in the DB
|
||||
$iLastOSMID = $oDB->getOne("select max(id) from planet_osm_nodes");
|
||||
$iLastOSMID = $oDB->getOne("select max(osm_id) from place where osm_type = 'N'");
|
||||
|
||||
// Lookup the timestamp that node was created (less 3 hours for margin for changsets to be closed)
|
||||
$sLastNodeURL = 'http://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID."/1";
|
||||
@@ -564,49 +596,59 @@
|
||||
|
||||
// Search for the correct state file - uses file timestamps so need to sort by date descending
|
||||
$sRepURL = CONST_Replication_Url."/";
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D");
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
|
||||
// download.geofabrik.de: <a href="000/">000/</a></td><td align="right">26-Feb-2013 11:53 </td>
|
||||
// planet.openstreetmap.org: <a href="273/">273/</a> 22-Mar-2013 07:41 -
|
||||
preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>.*(([0-9]{2})-([A-z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}))#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
// planet.openstreetmap.org: <a href="273/">273/</a> 2013-03-11 07:41 -
|
||||
preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
if ($aRepMatches)
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
|
||||
$sRepURL .= $aRepMatch[1];
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D");
|
||||
preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>.*(([0-9]{2})-([A-z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}))#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
$sRepURL .= $aRepMatch[1];
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
|
||||
preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
|
||||
$sRepURL .= $aRepMatch[1];
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
|
||||
preg_match_all('#<a href="[0-9]{3}.state.txt">([0-9]{3}).state.txt</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
|
||||
$sRepURL .= $aRepMatch[1].'.state.txt';
|
||||
echo "Getting state file: $sRepURL\n";
|
||||
$sStateFile = file_get_contents($sRepURL);
|
||||
if (!$sStateFile || strlen($sStateFile) > 1000) fail("unable to obtain state file");
|
||||
file_put_contents(CONST_BasePath.'/settings/state.txt', $sStateFile);
|
||||
echo "Updating DB status\n";
|
||||
pg_query($oDB->connection, 'TRUNCATE import_status');
|
||||
$sSQL = "INSERT INTO import_status VALUES('".$aRepMatch[2]."')";
|
||||
pg_query($oDB->connection, $sSQL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
if (!$aCMDResult['all'])
|
||||
{
|
||||
fail("Cannot read state file directory.");
|
||||
}
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
|
||||
$sRepURL .= $aRepMatch[1];
|
||||
$sRep = file_get_contents($sRepURL."?C=M;O=D");
|
||||
preg_match_all('#<a href="[0-9]{3}.state.txt">([0-9]{3}).state.txt</a>.*(([0-9]{2})-([A-z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}))#', $sRep, $aRepMatches, PREG_SET_ORDER);
|
||||
$aPrevRepMatch = false;
|
||||
foreach($aRepMatches as $aRepMatch)
|
||||
{
|
||||
if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
|
||||
$aPrevRepMatch = $aRepMatch;
|
||||
}
|
||||
if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
|
||||
|
||||
$sRepURL .= $aRepMatch[1].'.state.txt';
|
||||
echo "Getting state file: $sRepURL\n";
|
||||
$sStateFile = file_get_contents($sRepURL);
|
||||
if (!$sStateFile || strlen($sStateFile) > 1000) fail("unable to obtain state file");
|
||||
file_put_contents(CONST_BasePath.'/settings/state.txt', $sStateFile);
|
||||
echo "Updating DB status\n";
|
||||
pg_query($oDB->connection, 'TRUNCATE import_status');
|
||||
$sSQL = "INSERT INTO import_status VALUES('".$aRepMatch[2]."')";
|
||||
pg_query($oDB->connection, $sSQL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,6 +679,12 @@
|
||||
if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
|
||||
|
||||
$sTemplate = file_get_contents(CONST_BasePath.'/sql/indices.src.sql');
|
||||
$sTemplate = replace_tablespace('{ts:address-index}',
|
||||
CONST_Tablespace_Address_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:search-index}',
|
||||
CONST_Tablespace_Search_Index, $sTemplate);
|
||||
$sTemplate = replace_tablespace('{ts:aux-index}',
|
||||
CONST_Tablespace_Aux_Index, $sTemplate);
|
||||
preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
|
||||
foreach($aMatches as $aMatch)
|
||||
{
|
||||
@@ -665,6 +713,7 @@
|
||||
@symlink(CONST_BasePath.'/website/reverse.php', $sTargetDir.'/reverse.php');
|
||||
@symlink(CONST_BasePath.'/website/search.php', $sTargetDir.'/search.php');
|
||||
@symlink(CONST_BasePath.'/website/search.php', $sTargetDir.'/index.php');
|
||||
@symlink(CONST_BasePath.'/website/lookup.php', $sTargetDir.'/lookup.php');
|
||||
@symlink(CONST_BasePath.'/website/deletable.php', $sTargetDir.'/deletable.php');
|
||||
@symlink(CONST_BasePath.'/website/polygons.php', $sTargetDir.'/polygons.php');
|
||||
@symlink(CONST_BasePath.'/website/status.php', $sTargetDir.'/status.php');
|
||||
@@ -673,7 +722,7 @@
|
||||
@symlink(CONST_BasePath.'/website/css', $sTargetDir.'/css');
|
||||
echo "Symlinks created\n";
|
||||
|
||||
$sTestFile = @file_get_contents(CONST_Website_BaseURL.'js/tiles.js');
|
||||
$sTestFile = @file_get_contents(CONST_Website_BaseURL.'js/nominatim-ui.js');
|
||||
if (!$sTestFile)
|
||||
{
|
||||
echo "\nWARNING: Unable to access the website at ".CONST_Website_BaseURL."\n";
|
||||
@@ -681,6 +730,69 @@
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCMDResult['drop'])
|
||||
{
|
||||
// The implementation is potentially a bit dangerous because it uses
|
||||
// a positive selection of tables to keep, and deletes everything else.
|
||||
// Including any tables that the unsuspecting user might have manually
|
||||
// created. USE AT YOUR OWN PERIL.
|
||||
$bDidSomething = true;
|
||||
|
||||
// tables we want to keep. everything else goes.
|
||||
$aKeepTables = array(
|
||||
"*columns",
|
||||
"import_polygon_*",
|
||||
"import_status",
|
||||
"place_addressline",
|
||||
"location_property*",
|
||||
"placex",
|
||||
"search_name",
|
||||
"seq_*",
|
||||
"word",
|
||||
"query_log",
|
||||
"new_query_log",
|
||||
"gb_postcode",
|
||||
"spatial_ref_sys",
|
||||
"country_name",
|
||||
"place_classtype_*"
|
||||
);
|
||||
|
||||
$oDB =& getDB();
|
||||
$aDropTables = array();
|
||||
$aHaveTables = $oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'");
|
||||
if (PEAR::isError($aHaveTables))
|
||||
{
|
||||
fail($aPartitions->getMessage());
|
||||
}
|
||||
foreach($aHaveTables as $sTable)
|
||||
{
|
||||
$bFound = false;
|
||||
foreach ($aKeepTables as $sKeep)
|
||||
{
|
||||
if (fnmatch($sKeep, $sTable))
|
||||
{
|
||||
$bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$bFound) array_push($aDropTables, $sTable);
|
||||
}
|
||||
|
||||
foreach ($aDropTables as $sDrop)
|
||||
{
|
||||
if ($aCMDResult['verbose']) echo "dropping table $sDrop\n";
|
||||
@pg_query($oDB->connection, "DROP TABLE $sDrop CASCADE");
|
||||
// ignore warnings/errors as they might be caused by a table having
|
||||
// been deleted already by CASCADE
|
||||
}
|
||||
|
||||
if (!is_null(CONST_Osm2pgsql_Flatnode_File))
|
||||
{
|
||||
if ($aCMDResult['verbose']) echo "deleting ".CONST_Osm2pgsql_Flatnode_File."\n";
|
||||
unlink(CONST_Osm2pgsql_Flatnode_File);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bDidSomething)
|
||||
{
|
||||
showUsage($aCMDOptions, true);
|
||||
@@ -748,14 +860,14 @@
|
||||
|
||||
}
|
||||
|
||||
function pgsqlRunScript($sScript)
|
||||
function pgsqlRunScript($sScript, $bfatal = true)
|
||||
{
|
||||
global $aCMDResult;
|
||||
// Convert database DSN to psql parameters
|
||||
$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
|
||||
if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
|
||||
$sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
|
||||
if (!$aCMDResult['ignore-errors'])
|
||||
if ($bfatal && !$aCMDResult['ignore-errors'])
|
||||
$sCMD .= ' -v ON_ERROR_STOP=1';
|
||||
$aDescriptors = array(
|
||||
0 => array('pipe', 'r'),
|
||||
@@ -774,7 +886,7 @@
|
||||
}
|
||||
fclose($ahPipes[0]);
|
||||
$iReturn = proc_close($hProcess);
|
||||
if ($iReturn > 0)
|
||||
if ($bfatal && $iReturn > 0)
|
||||
{
|
||||
fail("pgsql returned with error code ($iReturn)");
|
||||
}
|
||||
@@ -842,3 +954,15 @@
|
||||
passthru($cmd, $result);
|
||||
if ($result != 0) fail('Error executing external command: '.$cmd);
|
||||
}
|
||||
|
||||
function replace_tablespace($sTemplate, $sTablespace, $sSql)
|
||||
{
|
||||
if ($sTablespace)
|
||||
$sSql = str_replace($sTemplate, 'TABLESPACE "'.$sTablespace.'"',
|
||||
$sSql);
|
||||
else
|
||||
$sSql = str_replace($sTemplate, '', $sSql);
|
||||
|
||||
return $sSql;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,17 +86,26 @@
|
||||
|
||||
foreach($aPairs as $aPair)
|
||||
{
|
||||
echo "create table place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." as ";
|
||||
echo "select place_id as place_id,st_centroid(geometry) as centroid from placex where ";
|
||||
echo "class = '".pg_escape_string($aPair[0])."' and type = '".pg_escape_string($aPair[1])."';\n";
|
||||
echo "create table place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]);
|
||||
if (CONST_Tablespace_Aux_Data)
|
||||
echo " tablespace ".CONST_Tablespace_Aux_Data;
|
||||
echo " as select place_id as place_id,st_centroid(geometry) as centroid from placex where ";
|
||||
echo "class = '".pg_escape_string($aPair[0])."' and type = '".pg_escape_string($aPair[1])."'";
|
||||
echo ";\n";
|
||||
|
||||
echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_centroid ";
|
||||
echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING GIST (centroid);\n";
|
||||
echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING GIST (centroid)";
|
||||
if (CONST_Tablespace_Aux_Index)
|
||||
echo " tablespace ".CONST_Tablespace_Aux_Index;
|
||||
echo ";\n";
|
||||
|
||||
echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_place_id ";
|
||||
echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING btree(place_id);\n";
|
||||
echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING btree(place_id)";
|
||||
if (CONST_Tablespace_Aux_Index)
|
||||
echo " tablespace ".CONST_Tablespace_Aux_Index;
|
||||
echo ";\n";
|
||||
|
||||
echo "GRANT SELECT ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." TO \"www-data\";";
|
||||
echo "GRANT SELECT ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]).' TO "'.CONST_Database_Web_User."\";\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -197,32 +197,33 @@ county_fips = {
|
||||
'02013' : 'Aleutians East, AK' ,
|
||||
'02016' : 'Aleutians West, AK' ,
|
||||
'02020' : 'Anchorage, AK' ,
|
||||
'02230' : 'Skagway Municipality' ,
|
||||
'02050' : 'Bethel, AK' ,
|
||||
'02060' : 'Bristol Bay, AK' ,
|
||||
'02068' : 'Denali, AK' ,
|
||||
'02070' : 'Dillingham, AK' ,
|
||||
'02090' : 'Fairbanks North Star, AK' ,
|
||||
'02100' : 'Haines, AK' ,
|
||||
'02105' : 'Hoonah-Angoon Census Area' ,
|
||||
'02105' : 'Hoonah-Angoon Census Area, AK' ,
|
||||
'02110' : 'Juneau, AK' ,
|
||||
'02122' : 'Kenai Peninsula, AK' ,
|
||||
'02130' : 'Ketchikan Gateway, AK' ,
|
||||
'02150' : 'Kodiak Island, AK' ,
|
||||
'02158' : 'Kusilvak Census Area, AK' ,
|
||||
'02164' : 'Lake and Peninsula, AK' ,
|
||||
'02170' : 'Matanuska-Susitna, AK' ,
|
||||
'02180' : 'Nome, AK' ,
|
||||
'02185' : 'North Slope, AK' ,
|
||||
'02188' : 'Northwest Arctic, AK' ,
|
||||
'02195' : 'Petersburg Census Area' ,
|
||||
'02198' : 'Prince of Wales-Hyder Census Area' ,
|
||||
'02195' : 'Petersburg, AK' ,
|
||||
'02198' : 'Prince of Wales-Hyder Census Area, AK' ,
|
||||
'02201' : 'Prince of Wales-Outer Ketchikan, AK' ,
|
||||
'02220' : 'Sitka, AK' ,
|
||||
'02230' : 'Skagway, AK' ,
|
||||
'02232' : 'Skagway-Hoonah-Angoon, AK' ,
|
||||
'02240' : 'Southeast Fairbanks, AK' ,
|
||||
'02261' : 'Valdez-Cordova, AK' ,
|
||||
'02270' : 'Wade Hampton, AK' ,
|
||||
'02275' : 'Wrangell City and Borough' ,
|
||||
'02275' : 'Wrangell City and Borough, AK' ,
|
||||
'02280' : 'Wrangell-Petersburg, AK' ,
|
||||
'02282' : 'Yakutat, AK' ,
|
||||
'02290' : 'Yukon-Koyukuk, AK' ,
|
||||
@@ -786,7 +787,7 @@ county_fips = {
|
||||
'17093' : 'Kendall, IL' ,
|
||||
'17095' : 'Knox, IL' ,
|
||||
'17097' : 'Lake, IL' ,
|
||||
'17099' : 'La Salle, IL' ,
|
||||
'17099' : 'LaSalle, IL' ,
|
||||
'17101' : 'Lawrence, IL' ,
|
||||
'17103' : 'Lee, IL' ,
|
||||
'17105' : 'Livingston, IL' ,
|
||||
@@ -1289,7 +1290,7 @@ county_fips = {
|
||||
'22053' : 'Jefferson Davis, LA' ,
|
||||
'22055' : 'Lafayette, LA' ,
|
||||
'22057' : 'Lafourche, LA' ,
|
||||
'22059' : 'La Salle, LA' ,
|
||||
'22059' : 'LaSalle, LA' ,
|
||||
'22061' : 'Lincoln, LA' ,
|
||||
'22063' : 'Livingston, LA' ,
|
||||
'22065' : 'Madison, LA' ,
|
||||
@@ -1365,7 +1366,7 @@ county_fips = {
|
||||
'24043' : 'Washington, MD' ,
|
||||
'24045' : 'Wicomico, MD' ,
|
||||
'24047' : 'Worcester, MD' ,
|
||||
'24510' : 'Baltimore city, MD' ,
|
||||
'24510' : 'Baltimore City, MD' ,
|
||||
'25000' : 'MASSACHUSETTS' ,
|
||||
'25001' : 'Barnstable, MA' ,
|
||||
'25003' : 'Berkshire, MA' ,
|
||||
@@ -1751,7 +1752,7 @@ county_fips = {
|
||||
'29225' : 'Webster, MO' ,
|
||||
'29227' : 'Worth, MO' ,
|
||||
'29229' : 'Wright, MO' ,
|
||||
'29510' : 'St. Louis city, MO' ,
|
||||
'29510' : 'St. Louis City, MO' ,
|
||||
'30000' : 'MONTANA' ,
|
||||
'30001' : 'Beaverhead, MT' ,
|
||||
'30003' : 'Big Horn, MT' ,
|
||||
@@ -1921,7 +1922,7 @@ county_fips = {
|
||||
'32029' : 'Storey, NV' ,
|
||||
'32031' : 'Washoe, NV' ,
|
||||
'32033' : 'White Pine, NV' ,
|
||||
'32510' : 'Carson City city, NV' ,
|
||||
'32510' : 'Carson City, NV' ,
|
||||
'33000' : 'NEW HAMPSHIRE' ,
|
||||
'33001' : 'Belknap, NH' ,
|
||||
'33003' : 'Carroll, NH' ,
|
||||
@@ -2583,6 +2584,7 @@ county_fips = {
|
||||
'46097' : 'Miner, SD' ,
|
||||
'46099' : 'Minnehaha, SD' ,
|
||||
'46101' : 'Moody, SD' ,
|
||||
'46102' : 'Oglala Lakota, SD' ,
|
||||
'46103' : 'Pennington, SD' ,
|
||||
'46105' : 'Perkins, SD' ,
|
||||
'46107' : 'Potter, SD' ,
|
||||
@@ -3326,97 +3328,97 @@ county_fips = {
|
||||
'56043' : 'Washakie, WY' ,
|
||||
'56045' : 'Weston, WY' ,
|
||||
'60000' : 'AMERICAN SAMOA',
|
||||
'60010' : 'Eastern district, AS' ,
|
||||
'60020' : 'Manua district, AS' ,
|
||||
'60030' : 'Rose island, AS' ,
|
||||
'60040' : 'Swains island, AS' ,
|
||||
'60050' : 'Western district, AS' ,
|
||||
'60010' : 'Eastern District, AS' ,
|
||||
'60020' : 'Manu\'a District, AS' ,
|
||||
'60030' : 'Rose Island, AS' ,
|
||||
'60040' : 'Swains Island, AS' ,
|
||||
'60050' : 'Western District, AS' ,
|
||||
'66000' : 'GUAM' ,
|
||||
'66010' : 'Guam, GU' ,
|
||||
'69000' : 'COMMONWEALTH OF THE NORTHERN MARIANA ISLANDS' ,
|
||||
'69085' : 'Commonwealth of the Northern Mariana Islands, MP' ,
|
||||
'69100' : 'Commonwealth of the Northern Mariana Islands, MP' ,
|
||||
'69110' : 'Commonwealth of the Northern Mariana Islands, MP' ,
|
||||
'69120' : 'Commonwealth of the Northern Mariana Islands, MP' ,
|
||||
'72000' : 'PUERTO RICO',
|
||||
'72001' : 'Adjuntas, PR',
|
||||
'72003' : 'Aguada, PR',
|
||||
'72005' : 'Aguadilla, PR',
|
||||
'72007' : 'Aguas Buenas, PR',
|
||||
'72009' : 'Aibonito, PR',
|
||||
'72011' : 'Anasco, PR',
|
||||
'72013' : 'Arecibo, PR',
|
||||
'72015' : 'Arroyo, PR',
|
||||
'72017' : 'Barceloneta, PR',
|
||||
'72019' : 'Barranquitas, PR',
|
||||
'72021' : 'Bayamon, PR',
|
||||
'72023' : 'Cabo Rojo, PR',
|
||||
'72025' : 'Caguas, PR',
|
||||
'72027' : 'Camuy, PR',
|
||||
'72029' : 'Canovanas, PR',
|
||||
'72031' : 'Carolina, PR',
|
||||
'72033' : 'Catano, PR',
|
||||
'72035' : 'Cayey, PR',
|
||||
'72037' : 'Ceiba, PR',
|
||||
'72039' : 'Ciales, PR',
|
||||
'72041' : 'Cidra, PR',
|
||||
'72043' : 'Coamo, PR',
|
||||
'72045' : 'Comerio, PR',
|
||||
'72047' : 'Corozal, PR',
|
||||
'72049' : 'Culebra, PR',
|
||||
'72051' : 'Dorado, PR',
|
||||
'72053' : 'Fajardo, PR',
|
||||
'72054' : 'Florida, PR',
|
||||
'72055' : 'Guanica, PR',
|
||||
'72057' : 'Guayama, PR',
|
||||
'72059' : 'Guayanilla, PR',
|
||||
'72061' : 'Guaynabo, PR',
|
||||
'72063' : 'Gurabo, PR',
|
||||
'72065' : 'Hatillo, PR',
|
||||
'72067' : 'Hormigueros, PR',
|
||||
'72069' : 'Humacao, PR',
|
||||
'72071' : 'Isabela, PR',
|
||||
'72073' : 'Jayuya, PR',
|
||||
'72075' : 'Juana Diaz, PR',
|
||||
'72077' : 'Juncos, PR',
|
||||
'72079' : 'Lajas, PR',
|
||||
'72081' : 'Lares, PR',
|
||||
'72083' : 'Las Marias, PR',
|
||||
'72085' : 'Las Piedras, PR',
|
||||
'72087' : 'Loiza, PR',
|
||||
'72089' : 'Luquillo, PR',
|
||||
'72091' : 'Manati, PR',
|
||||
'72093' : 'Maricao, PR',
|
||||
'72095' : 'Maunabo, PR',
|
||||
'72097' : 'Mayaguez, PR',
|
||||
'72099' : 'Moca, PR',
|
||||
'72101' : 'Morovis, PR',
|
||||
'72103' : 'Naguabo, PR',
|
||||
'72105' : 'Naranjito, PR',
|
||||
'72107' : 'Orocovis, PR',
|
||||
'72109' : 'Patillas, PR',
|
||||
'72111' : 'Penuelas, PR',
|
||||
'72113' : 'Ponce, PR',
|
||||
'72115' : 'Quebradillas, PR',
|
||||
'72117' : 'Rincon, PR',
|
||||
'72119' : 'Rio Grande, PR',
|
||||
'72121' : 'Sabana Grande, PR',
|
||||
'72123' : 'Salinas, PR',
|
||||
'72125' : 'San German, PR',
|
||||
'72127' : 'San Juan, PR',
|
||||
'72129' : 'San Lorenzo, PR',
|
||||
'72131' : 'San Sebastian, PR',
|
||||
'72133' : 'Santa Isabel, PR',
|
||||
'72135' : 'Toa Alta, PR',
|
||||
'72137' : 'Toa Baja, PR',
|
||||
'72139' : 'Trujillo Alto, PR',
|
||||
'72141' : 'Utuado, PR',
|
||||
'72143' : 'Vega Alta, PR',
|
||||
'72145' : 'Vega Baja, PR',
|
||||
'72147' : 'Vieques, PR',
|
||||
'72149' : 'Villalba, PR',
|
||||
'72151' : 'Yabucoa, PR',
|
||||
'72153' : 'Yauco, PR',
|
||||
'69085' : 'Northern Islands, MP' ,
|
||||
'69100' : 'Rota, MP' ,
|
||||
'69110' : 'Saipan, MP' ,
|
||||
'69120' : 'Tinian, MP' ,
|
||||
'72000' : 'PUERTO RICO' ,
|
||||
'72001' : 'Adjuntas, PR' ,
|
||||
'72003' : 'Aguada, PR' ,
|
||||
'72005' : 'Aguadilla, PR' ,
|
||||
'72007' : 'Aguas Buenas, PR' ,
|
||||
'72009' : 'Aibonito, PR' ,
|
||||
'72011' : 'Anasco, PR' ,
|
||||
'72013' : 'Arecibo, PR' ,
|
||||
'72015' : 'Arroyo, PR' ,
|
||||
'72017' : 'Barceloneta, PR' ,
|
||||
'72019' : 'Barranquitas, PR' ,
|
||||
'72021' : 'Bayamon, PR' ,
|
||||
'72023' : 'Cabo Rojo, PR' ,
|
||||
'72025' : 'Caguas, PR' ,
|
||||
'72027' : 'Camuy, PR' ,
|
||||
'72029' : 'Canovanas, PR' ,
|
||||
'72031' : 'Carolina, PR' ,
|
||||
'72033' : 'Catano, PR' ,
|
||||
'72035' : 'Cayey, PR' ,
|
||||
'72037' : 'Ceiba, PR' ,
|
||||
'72039' : 'Ciales, PR' ,
|
||||
'72041' : 'Cidra, PR' ,
|
||||
'72043' : 'Coamo, PR' ,
|
||||
'72045' : 'Comerio, PR' ,
|
||||
'72047' : 'Corozal, PR' ,
|
||||
'72049' : 'Culebra, PR' ,
|
||||
'72051' : 'Dorado, PR' ,
|
||||
'72053' : 'Fajardo, PR' ,
|
||||
'72054' : 'Florida, PR' ,
|
||||
'72055' : 'Guanica, PR' ,
|
||||
'72057' : 'Guayama, PR' ,
|
||||
'72059' : 'Guayanilla, PR' ,
|
||||
'72061' : 'Guaynabo, PR' ,
|
||||
'72063' : 'Gurabo, PR' ,
|
||||
'72065' : 'Hatillo, PR' ,
|
||||
'72067' : 'Hormigueros, PR' ,
|
||||
'72069' : 'Humacao, PR' ,
|
||||
'72071' : 'Isabela, PR' ,
|
||||
'72073' : 'Jayuya, PR' ,
|
||||
'72075' : 'Juana Diaz, PR' ,
|
||||
'72077' : 'Juncos, PR' ,
|
||||
'72079' : 'Lajas, PR' ,
|
||||
'72081' : 'Lares, PR' ,
|
||||
'72083' : 'Las Marias, PR' ,
|
||||
'72085' : 'Las Piedras, PR' ,
|
||||
'72087' : 'Loiza, PR' ,
|
||||
'72089' : 'Luquillo, PR' ,
|
||||
'72091' : 'Manati, PR' ,
|
||||
'72093' : 'Maricao, PR' ,
|
||||
'72095' : 'Maunabo, PR' ,
|
||||
'72097' : 'Mayaguez, PR' ,
|
||||
'72099' : 'Moca, PR' ,
|
||||
'72101' : 'Morovis, PR' ,
|
||||
'72103' : 'Naguabo, PR' ,
|
||||
'72105' : 'Naranjito, PR' ,
|
||||
'72107' : 'Orocovis, PR' ,
|
||||
'72109' : 'Patillas, PR' ,
|
||||
'72111' : 'Penuelas, PR' ,
|
||||
'72113' : 'Ponce, PR' ,
|
||||
'72115' : 'Quebradillas, PR' ,
|
||||
'72117' : 'Rincon, PR' ,
|
||||
'72119' : 'Rio Grande, PR' ,
|
||||
'72121' : 'Sabana Grande, PR' ,
|
||||
'72123' : 'Salinas, PR' ,
|
||||
'72125' : 'San German, PR' ,
|
||||
'72127' : 'San Juan, PR' ,
|
||||
'72129' : 'San Lorenzo, PR' ,
|
||||
'72131' : 'San Sebastian, PR' ,
|
||||
'72133' : 'Santa Isabel, PR' ,
|
||||
'72135' : 'Toa Alta, PR' ,
|
||||
'72137' : 'Toa Baja, PR' ,
|
||||
'72139' : 'Trujillo Alto, PR' ,
|
||||
'72141' : 'Utuado, PR' ,
|
||||
'72143' : 'Vega Alta, PR' ,
|
||||
'72145' : 'Vega Baja, PR' ,
|
||||
'72147' : 'Vieques, PR' ,
|
||||
'72149' : 'Villalba, PR' ,
|
||||
'72151' : 'Yabucoa, PR' ,
|
||||
'72153' : 'Yauco, PR' ,
|
||||
'78000' : 'VIRGIN ISLANDS' ,
|
||||
'78010' : 'St. Croix, VI' ,
|
||||
'78020' : 'St. John, VI' ,
|
||||
@@ -3433,7 +3435,7 @@ def fipsstate(fips,countyfp):
|
||||
return tags
|
||||
|
||||
if fips not in fipscodes:
|
||||
raise KeyError, 'missing FIPS code', fips
|
||||
raise KeyError('missing FIPS code', fips)
|
||||
|
||||
state, statecode, isocode = fipscodes[fips]
|
||||
county_fips_code = fips + "" + countyfp
|
||||
@@ -3478,69 +3480,69 @@ def parse_shp_for_osm( filename ):
|
||||
# WAY ID
|
||||
tags[iSource + ":way_id"] = int( poFeature.GetField("TLID") )
|
||||
|
||||
# FEATURE IDENTIFICATION
|
||||
# FEATURE IDENTIFICATION
|
||||
mtfcc = poFeature.GetField("MTFCC");
|
||||
if mtfcc != None:
|
||||
|
||||
if mtfcc == "L4010": #Pipeline
|
||||
tags["man_made"] = "pipeline"
|
||||
if mtfcc == "L4020": #Powerline
|
||||
tags["power"] = "line"
|
||||
if mtfcc == "L4031": #Aerial Tramway/Ski Lift
|
||||
tags["aerialway"] = "cable_car"
|
||||
if mtfcc == "L4110": #Fence Line
|
||||
tags["barrier"] = "fence"
|
||||
if mtfcc == "L4125": #Cliff/Escarpment
|
||||
tags["natural"] = "cliff"
|
||||
if mtfcc == "L4165": #Ferry Crossing
|
||||
tags["route"] = "ferry"
|
||||
if mtfcc == "R1011": #Railroad Feature (Main, Spur, or Yard)
|
||||
tags["railway"] = "rail"
|
||||
ttyp = poFeature.GetField("TTYP")
|
||||
if ttyp != None:
|
||||
if ttyp == "S":
|
||||
tags["service"] = "spur"
|
||||
if ttyp == "Y":
|
||||
tags["service"] = "yard"
|
||||
tags["tiger:ttyp"] = ttyp
|
||||
if mtfcc == "R1051": #Carline, Streetcar Track, Monorail, Other Mass Transit Rail)
|
||||
tags["railway"] = "light_rail"
|
||||
if mtfcc == "R1052": #Cog Rail Line, Incline Rail Line, Tram
|
||||
tags["railway"] = "incline"
|
||||
if mtfcc == "S1100":
|
||||
tags["highway"] = "primary"
|
||||
if mtfcc == "S1200":
|
||||
tags["highway"] = "secondary"
|
||||
if mtfcc == "S1400":
|
||||
tags["highway"] = "residential"
|
||||
if mtfcc == "S1500":
|
||||
tags["highway"] = "track"
|
||||
if mtfcc == "S1630": #Ramp
|
||||
tags["highway"] = "motorway_link"
|
||||
if mtfcc == "S1640": #Service Drive usually along a limited access highway
|
||||
tags["highway"] = "service"
|
||||
if mtfcc == "S1710": #Walkway/Pedestrian Trail
|
||||
tags["highway"] = "path"
|
||||
if mtfcc == "S1720":
|
||||
tags["highway"] = "steps"
|
||||
if mtfcc == "S1730": #Alley
|
||||
tags["highway"] = "service"
|
||||
tags["service"] = "alley"
|
||||
if mtfcc == "S1740": #Private Road for service vehicles (logging, oil, fields, ranches, etc.)
|
||||
tags["highway"] = "service"
|
||||
tags["access"] = "private"
|
||||
if mtfcc == "S1750": #Private Driveway
|
||||
tags["highway"] = "service"
|
||||
tags["access"] = "private"
|
||||
tags["service"] = "driveway"
|
||||
if mtfcc == "S1780": #Parking Lot Road
|
||||
tags["highway"] = "service"
|
||||
tags["service"] = "parking_aisle"
|
||||
if mtfcc == "S1820": #Bike Path or Trail
|
||||
tags["highway"] = "cycleway"
|
||||
if mtfcc == "S1830": #Bridle Path
|
||||
tags["highway"] = "bridleway"
|
||||
tags["tiger:mtfcc"] = mtfcc
|
||||
if mtfcc == "L4010": #Pipeline
|
||||
tags["man_made"] = "pipeline"
|
||||
if mtfcc == "L4020": #Powerline
|
||||
tags["power"] = "line"
|
||||
if mtfcc == "L4031": #Aerial Tramway/Ski Lift
|
||||
tags["aerialway"] = "cable_car"
|
||||
if mtfcc == "L4110": #Fence Line
|
||||
tags["barrier"] = "fence"
|
||||
if mtfcc == "L4125": #Cliff/Escarpment
|
||||
tags["natural"] = "cliff"
|
||||
if mtfcc == "L4165": #Ferry Crossing
|
||||
tags["route"] = "ferry"
|
||||
if mtfcc == "R1011": #Railroad Feature (Main, Spur, or Yard)
|
||||
tags["railway"] = "rail"
|
||||
ttyp = poFeature.GetField("TTYP")
|
||||
if ttyp != None:
|
||||
if ttyp == "S":
|
||||
tags["service"] = "spur"
|
||||
if ttyp == "Y":
|
||||
tags["service"] = "yard"
|
||||
tags["tiger:ttyp"] = ttyp
|
||||
if mtfcc == "R1051": #Carline, Streetcar Track, Monorail, Other Mass Transit Rail)
|
||||
tags["railway"] = "light_rail"
|
||||
if mtfcc == "R1052": #Cog Rail Line, Incline Rail Line, Tram
|
||||
tags["railway"] = "incline"
|
||||
if mtfcc == "S1100":
|
||||
tags["highway"] = "primary"
|
||||
if mtfcc == "S1200":
|
||||
tags["highway"] = "secondary"
|
||||
if mtfcc == "S1400":
|
||||
tags["highway"] = "residential"
|
||||
if mtfcc == "S1500":
|
||||
tags["highway"] = "track"
|
||||
if mtfcc == "S1630": #Ramp
|
||||
tags["highway"] = "motorway_link"
|
||||
if mtfcc == "S1640": #Service Drive usually along a limited access highway
|
||||
tags["highway"] = "service"
|
||||
if mtfcc == "S1710": #Walkway/Pedestrian Trail
|
||||
tags["highway"] = "path"
|
||||
if mtfcc == "S1720":
|
||||
tags["highway"] = "steps"
|
||||
if mtfcc == "S1730": #Alley
|
||||
tags["highway"] = "service"
|
||||
tags["service"] = "alley"
|
||||
if mtfcc == "S1740": #Private Road for service vehicles (logging, oil, fields, ranches, etc.)
|
||||
tags["highway"] = "service"
|
||||
tags["access"] = "private"
|
||||
if mtfcc == "S1750": #Private Driveway
|
||||
tags["highway"] = "service"
|
||||
tags["access"] = "private"
|
||||
tags["service"] = "driveway"
|
||||
if mtfcc == "S1780": #Parking Lot Road
|
||||
tags["highway"] = "service"
|
||||
tags["service"] = "parking_aisle"
|
||||
if mtfcc == "S1820": #Bike Path or Trail
|
||||
tags["highway"] = "cycleway"
|
||||
if mtfcc == "S1830": #Bridle Path
|
||||
tags["highway"] = "bridleway"
|
||||
tags["tiger:mtfcc"] = mtfcc
|
||||
|
||||
# FEATURE NAME
|
||||
if poFeature.GetField("FULLNAME"):
|
||||
@@ -3548,20 +3550,20 @@ def parse_shp_for_osm( filename ):
|
||||
name = poFeature.GetField( "FULLNAME" )
|
||||
tags["name"] = name
|
||||
|
||||
#Attempt to guess highway grade
|
||||
if name[0:2] == "I-":
|
||||
tags["highway"] = "motorway"
|
||||
if name[0:3] == "US ":
|
||||
tags["highway"] = "primary"
|
||||
if name[0:3] == "US-":
|
||||
tags["highway"] = "primary"
|
||||
if name[0:3] == "Hwy":
|
||||
if tags["highway"] != "primary":
|
||||
tags["highway"] = "secondary"
|
||||
#Attempt to guess highway grade
|
||||
if name[0:2] == "I-":
|
||||
tags["highway"] = "motorway"
|
||||
if name[0:3] == "US ":
|
||||
tags["highway"] = "primary"
|
||||
if name[0:3] == "US-":
|
||||
tags["highway"] = "primary"
|
||||
if name[0:3] == "Hwy":
|
||||
if tags["highway"] != "primary":
|
||||
tags["highway"] = "secondary"
|
||||
|
||||
divroad = poFeature.GetField("DIVROAD")
|
||||
if divroad != None:
|
||||
if divroad == "Y" and "highway" in tags and tags["highway"] == "residential":
|
||||
if divroad == "Y" and "highway" in tags and tags["highway"] == "residential":
|
||||
tags["highway"] = "tertiary"
|
||||
tags["tiger:separated"] = divroad
|
||||
|
||||
@@ -3618,10 +3620,10 @@ def parse_shp_for_osm( filename ):
|
||||
# ====================================
|
||||
projcs_wkt = \
|
||||
"""GEOGCS["GCS_North_American_1983",
|
||||
DATUM["D_North_American_1983",
|
||||
SPHEROID["GRS_1980",6378137,298.257222101]],
|
||||
PRIMEM["Greenwich",0],
|
||||
UNIT["Degree",0.017453292519943295]]"""
|
||||
DATUM["D_North_American_1983",
|
||||
SPHEROID["GRS_1980",6378137,298.257222101]],
|
||||
PRIMEM["Greenwich",0],
|
||||
UNIT["Degree",0.017453292519943295]]"""
|
||||
|
||||
from_proj = osr.SpatialReference()
|
||||
from_proj.ImportFromWkt( projcs_wkt )
|
||||
@@ -3642,12 +3644,12 @@ def length(segment, nodelist):
|
||||
pointid, (lat, lon) = nodelist[ round_point( point ) ]
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
#The approximate number of feet in one degree of longitute
|
||||
else:
|
||||
#The approximate number of feet in one degree of longitute
|
||||
lrad = math.radians(lat)
|
||||
lon_feet = 365527.822 * math.cos(lrad) - 306.75853 * math.cos(3 * lrad) + 0.3937 * math.cos(5 * lrad)
|
||||
distance += math.sqrt(((lat - previous[0])*lat_feet)**2 + ((lon - previous[1])*lon_feet)**2)
|
||||
previous = (lat, lon)
|
||||
distance += math.sqrt(((lat - previous[0])*lat_feet)**2 + ((lon - previous[1])*lon_feet)**2)
|
||||
previous = (lat, lon)
|
||||
return distance
|
||||
|
||||
def addressways(waylist, nodelist, first_id):
|
||||
@@ -3657,7 +3659,7 @@ def addressways(waylist, nodelist, first_id):
|
||||
distance = float(address_distance)
|
||||
ret = []
|
||||
|
||||
for waykey, segments in waylist.iteritems():
|
||||
for waykey, segments in waylist.items():
|
||||
waykey = dict(waykey)
|
||||
rsegments = []
|
||||
lsegments = []
|
||||
@@ -3666,11 +3668,11 @@ def addressways(waylist, nodelist, first_id):
|
||||
rsegment = []
|
||||
lastpoint = None
|
||||
|
||||
#Don't pull back the ends of very short ways too much
|
||||
seglength = length(segment, nodelist)
|
||||
if seglength < float(address_pullback) * 3.0:
|
||||
pullback = seglength / 3.0
|
||||
else:
|
||||
#Don't pull back the ends of very short ways too much
|
||||
seglength = length(segment, nodelist)
|
||||
if seglength < float(address_pullback) * 3.0:
|
||||
pullback = seglength / 3.0
|
||||
else:
|
||||
pullback = float(address_pullback)
|
||||
if "tiger:lfromadd" in waykey:
|
||||
lfromadd = waykey["tiger:lfromadd"]
|
||||
@@ -3687,88 +3689,88 @@ def addressways(waylist, nodelist, first_id):
|
||||
if "tiger:rtoadd" in waykey:
|
||||
rtoadd = waykey["tiger:rtoadd"]
|
||||
else:
|
||||
rtoadd = None
|
||||
rtoadd = None
|
||||
if rfromadd != None and rtoadd != None:
|
||||
right = True
|
||||
else:
|
||||
right = False
|
||||
else:
|
||||
right = False
|
||||
if lfromadd != None and ltoadd != None:
|
||||
left = True
|
||||
else:
|
||||
left = False
|
||||
else:
|
||||
left = False
|
||||
if left or right:
|
||||
first = True
|
||||
first = True
|
||||
firstpointid, firstpoint = nodelist[ round_point( segment[0] ) ]
|
||||
|
||||
finalpointid, finalpoint = nodelist[ round_point( segment[len(segment) - 1] ) ]
|
||||
for point in segment:
|
||||
pointid, (lat, lon) = nodelist[ round_point( point ) ]
|
||||
|
||||
#The approximate number of feet in one degree of longitute
|
||||
#The approximate number of feet in one degree of longitute
|
||||
lrad = math.radians(lat)
|
||||
lon_feet = 365527.822 * math.cos(lrad) - 306.75853 * math.cos(3 * lrad) + 0.3937 * math.cos(5 * lrad)
|
||||
|
||||
#Calculate the points of the offset ways
|
||||
if lastpoint != None:
|
||||
#Skip points too close to start
|
||||
if math.sqrt((lat * lat_feet - firstpoint[0] * lat_feet)**2 + (lon * lon_feet - firstpoint[1] * lon_feet)**2) < pullback:
|
||||
#Preserve very short ways (but will be rendered backwards)
|
||||
if pointid != finalpointid:
|
||||
continue
|
||||
#Skip points too close to end
|
||||
if math.sqrt((lat * lat_feet - finalpoint[0] * lat_feet)**2 + (lon * lon_feet - finalpoint[1] * lon_feet)**2) < pullback:
|
||||
#Preserve very short ways (but will be rendered backwards)
|
||||
if (pointid != firstpointid) and (pointid != finalpointid):
|
||||
continue
|
||||
#Skip points too close to start
|
||||
if math.sqrt((lat * lat_feet - firstpoint[0] * lat_feet)**2 + (lon * lon_feet - firstpoint[1] * lon_feet)**2) < pullback:
|
||||
#Preserve very short ways (but will be rendered backwards)
|
||||
if pointid != finalpointid:
|
||||
continue
|
||||
#Skip points too close to end
|
||||
if math.sqrt((lat * lat_feet - finalpoint[0] * lat_feet)**2 + (lon * lon_feet - finalpoint[1] * lon_feet)**2) < pullback:
|
||||
#Preserve very short ways (but will be rendered backwards)
|
||||
if (pointid != firstpointid) and (pointid != finalpointid):
|
||||
continue
|
||||
|
||||
X = (lon - lastpoint[1]) * lon_feet
|
||||
Y = (lat - lastpoint[0]) * lat_feet
|
||||
Y = (lat - lastpoint[0]) * lat_feet
|
||||
if Y != 0:
|
||||
theta = math.pi/2 - math.atan( X / Y)
|
||||
Xp = math.sin(theta) * distance
|
||||
Yp = math.cos(theta) * distance
|
||||
theta = math.pi/2 - math.atan( X / Y)
|
||||
Xp = math.sin(theta) * distance
|
||||
Yp = math.cos(theta) * distance
|
||||
else:
|
||||
Xp = 0
|
||||
if X > 0:
|
||||
if X > 0:
|
||||
Yp = -distance
|
||||
else:
|
||||
else:
|
||||
Yp = distance
|
||||
|
||||
if Y > 0:
|
||||
Xp = -Xp
|
||||
else:
|
||||
Yp = -Yp
|
||||
|
||||
if first:
|
||||
first = False
|
||||
dX = - (Yp * (pullback / distance)) / lon_feet #Pull back the first point
|
||||
dY = (Xp * (pullback / distance)) / lat_feet
|
||||
if left:
|
||||
if Y > 0:
|
||||
Xp = -Xp
|
||||
else:
|
||||
Yp = -Yp
|
||||
|
||||
if first:
|
||||
first = False
|
||||
dX = - (Yp * (pullback / distance)) / lon_feet #Pull back the first point
|
||||
dY = (Xp * (pullback / distance)) / lat_feet
|
||||
if left:
|
||||
lpoint = (lastpoint[0] + (Yp / lat_feet) - dY, lastpoint[1] + (Xp / lon_feet) - dX)
|
||||
lsegment.append( (id, lpoint) )
|
||||
id += 1
|
||||
if right:
|
||||
id += 1
|
||||
if right:
|
||||
rpoint = (lastpoint[0] - (Yp / lat_feet) - dY, lastpoint[1] - (Xp / lon_feet) - dX)
|
||||
rsegment.append( (id, rpoint) )
|
||||
id += 1
|
||||
id += 1
|
||||
|
||||
else:
|
||||
#round the curves
|
||||
if delta[1] != 0:
|
||||
theta = abs(math.atan(delta[0] / delta[1]))
|
||||
else:
|
||||
theta = math.pi / 2
|
||||
if Xp != 0:
|
||||
theta = theta - abs(math.atan(Yp / Xp))
|
||||
else: theta = theta - math.pi / 2
|
||||
r = 1 + abs(math.tan(theta/2))
|
||||
if left:
|
||||
lpoint = (lastpoint[0] + (Yp + delta[0]) * r / (lat_feet * 2), lastpoint[1] + (Xp + delta[1]) * r / (lon_feet * 2))
|
||||
else:
|
||||
#round the curves
|
||||
if delta[1] != 0:
|
||||
theta = abs(math.atan(delta[0] / delta[1]))
|
||||
else:
|
||||
theta = math.pi / 2
|
||||
if Xp != 0:
|
||||
theta = theta - abs(math.atan(Yp / Xp))
|
||||
else: theta = theta - math.pi / 2
|
||||
r = 1 + abs(math.tan(theta/2))
|
||||
if left:
|
||||
lpoint = (lastpoint[0] + (Yp + delta[0]) * r / (lat_feet * 2), lastpoint[1] + (Xp + delta[1]) * r / (lon_feet * 2))
|
||||
lsegment.append( (id, lpoint) )
|
||||
id += 1
|
||||
if right:
|
||||
if right:
|
||||
rpoint = (lastpoint[0] - (Yp + delta[0]) * r / (lat_feet * 2), lastpoint[1] - (Xp + delta[1]) * r / (lon_feet * 2))
|
||||
|
||||
|
||||
rsegment.append( (id, rpoint) )
|
||||
id += 1
|
||||
|
||||
@@ -3778,116 +3780,116 @@ def addressways(waylist, nodelist, first_id):
|
||||
|
||||
|
||||
#Add in the last node
|
||||
dX = - (Yp * (pullback / distance)) / lon_feet
|
||||
dY = (Xp * (pullback / distance)) / lat_feet
|
||||
if left:
|
||||
dX = - (Yp * (pullback / distance)) / lon_feet
|
||||
dY = (Xp * (pullback / distance)) / lat_feet
|
||||
if left:
|
||||
lpoint = (lastpoint[0] + (Yp + delta[0]) / (lat_feet * 2) + dY, lastpoint[1] + (Xp + delta[1]) / (lon_feet * 2) + dX )
|
||||
lsegment.append( (id, lpoint) )
|
||||
id += 1
|
||||
if right:
|
||||
if right:
|
||||
rpoint = (lastpoint[0] - Yp / lat_feet + dY, lastpoint[1] - Xp / lon_feet + dX)
|
||||
rsegment.append( (id, rpoint) )
|
||||
id += 1
|
||||
|
||||
#Generate the tags for ways and nodes
|
||||
rtags = []
|
||||
ltags = []
|
||||
tags = []
|
||||
rtags = []
|
||||
ltags = []
|
||||
tags = []
|
||||
zipr = ''
|
||||
zipl = ''
|
||||
name = ''
|
||||
county = ''
|
||||
if "tiger:zip_right" in waykey:
|
||||
zipr = waykey["tiger:zip_right"]
|
||||
if "tiger:zip_right" in waykey:
|
||||
zipr = waykey["tiger:zip_right"]
|
||||
rtags.append( "<tag k=\"addr:postcode\" v=\"%s\" />" % zipr )
|
||||
if "tiger:zip_left" in waykey:
|
||||
zipl = waykey["tiger:zip_left"]
|
||||
if "tiger:zip_left" in waykey:
|
||||
zipl = waykey["tiger:zip_left"]
|
||||
ltags.append( "<tag k=\"addr:postcode\" v=\"%s\" />" % zipl )
|
||||
if "name" in waykey:
|
||||
name = waykey["name"]
|
||||
tags.append( "<tag k=\"addr:street\" v=\"%s\" />" % name )
|
||||
if "is_in:state" in waykey:
|
||||
state = waykey["is_in:state"]
|
||||
if "is_in:state" in waykey:
|
||||
state = waykey["is_in:state"]
|
||||
tags.append( "<tag k=\"addr:state\" v=\"%s\" />" % state )
|
||||
if "tiger:county" in waykey:
|
||||
county = waykey["tiger:county"]
|
||||
if "tiger:county" in waykey:
|
||||
county = waykey["tiger:county"]
|
||||
tags.append( "<tag k=\"addr:county\" v=\"%s\" />" % county )
|
||||
if "is_in:country_code" in waykey:
|
||||
country = waykey["is_in:country_code"]
|
||||
if "is_in:country_code" in waykey:
|
||||
country = waykey["is_in:country_code"]
|
||||
tags.append( "<tag k=\"addr:country\" v=\"%s\" />" % country )
|
||||
if "tiger:separated" in waykey:
|
||||
separated = waykey["tiger:separated"]
|
||||
else:
|
||||
separated = "N"
|
||||
ltags.extend(tags)
|
||||
rtags.extend(tags)
|
||||
if "tiger:separated" in waykey:
|
||||
separated = waykey["tiger:separated"]
|
||||
else:
|
||||
separated = "N"
|
||||
ltags.extend(tags)
|
||||
rtags.extend(tags)
|
||||
|
||||
#Write the nodes of the offset ways
|
||||
if right:
|
||||
if right:
|
||||
rlinestring = [];
|
||||
for i, point in rsegment:
|
||||
rlinestring.append( "%f %f" % (point[1], point[0]) )
|
||||
if left:
|
||||
if left:
|
||||
llinestring = [];
|
||||
for i, point in lsegment:
|
||||
llinestring.append( "%f %f" % (point[1], point[0]) )
|
||||
if right:
|
||||
if right:
|
||||
rsegments.append( rsegment )
|
||||
if left:
|
||||
if left:
|
||||
lsegments.append( lsegment )
|
||||
rtofromint = right #Do the addresses convert to integers?
|
||||
ltofromint = left #Do the addresses convert to integers?
|
||||
if right:
|
||||
try: rfromint = int(rfromadd)
|
||||
except:
|
||||
print("Non integer address: %s" % rfromadd)
|
||||
rtofromint = False
|
||||
try: rtoint = int(rtoadd)
|
||||
except:
|
||||
print("Non integer address: %s" % rtoadd)
|
||||
rtofromint = False
|
||||
if left:
|
||||
try: lfromint = int(lfromadd)
|
||||
except:
|
||||
print("Non integer address: %s" % lfromadd)
|
||||
ltofromint = False
|
||||
try: ltoint = int(ltoadd)
|
||||
except:
|
||||
print("Non integer address: %s" % ltoadd)
|
||||
ltofromint = False
|
||||
import_guid = time.strftime( '%Y%m%d%H%M%S' )
|
||||
if right:
|
||||
id += 1
|
||||
rtofromint = right #Do the addresses convert to integers?
|
||||
ltofromint = left #Do the addresses convert to integers?
|
||||
if right:
|
||||
try: rfromint = int(rfromadd)
|
||||
except:
|
||||
print("Non integer address: %s" % rfromadd)
|
||||
rtofromint = False
|
||||
try: rtoint = int(rtoadd)
|
||||
except:
|
||||
print("Non integer address: %s" % rtoadd)
|
||||
rtofromint = False
|
||||
if left:
|
||||
try: lfromint = int(lfromadd)
|
||||
except:
|
||||
print("Non integer address: %s" % lfromadd)
|
||||
ltofromint = False
|
||||
try: ltoint = int(ltoadd)
|
||||
except:
|
||||
print("Non integer address: %s" % ltoadd)
|
||||
ltofromint = False
|
||||
import_guid = time.strftime( '%Y%m%d%H%M%S' )
|
||||
if right:
|
||||
id += 1
|
||||
|
||||
interpolationtype = "";
|
||||
if rtofromint:
|
||||
if rtofromint:
|
||||
if (rfromint % 2) == 0 and (rtoint % 2) == 0:
|
||||
if separated == "Y": #Doesn't matter if there is another side
|
||||
if separated == "Y": #Doesn't matter if there is another side
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"even\" />" )
|
||||
interpolationtype = "even";
|
||||
elif ltofromint and (lfromint % 2) == 1 and (ltoint % 2) == 1:
|
||||
elif ltofromint and (lfromint % 2) == 1 and (ltoint % 2) == 1:
|
||||
interpolationtype = "even";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"even\" />" )
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"all\" />" )
|
||||
elif (rfromint % 2) == 1 and (rtoint % 2) == 1:
|
||||
if separated == "Y": #Doesn't matter if there is another side
|
||||
if separated == "Y": #Doesn't matter if there is another side
|
||||
interpolationtype = "odd";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"odd\" />" )
|
||||
elif ltofromint and (lfromint % 2) == 0 and (ltoint % 2) == 0:
|
||||
elif ltofromint and (lfromint % 2) == 0 and (ltoint % 2) == 0:
|
||||
interpolationtype = "odd";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"odd\" />" )
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"all\" />" )
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"all\" />" )
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
# ret.append( "<tag k=\"addr:interpolation\" v=\"all\" />" )
|
||||
# ret.extend(rtags)
|
||||
# ret.extend(rtags)
|
||||
# ret.append( "<tag k=\"source\" v=\"%s_import_v%s_%s\" />" % (iSource, VERSION, import_guid) )
|
||||
# ret.append( "<tag k=\"attribution\" v=\"%s\" />" % (iAttrib) )
|
||||
# ret.append( "</way>" )
|
||||
@@ -3895,27 +3897,27 @@ def addressways(waylist, nodelist, first_id):
|
||||
ret.append( "select tigger_create_interpolation(ST_GeomFromText('LINESTRING(%s)',4326), '%s', '%s', '%s', '%s', '%s', '%s');" %
|
||||
( ",".join(rlinestring), rfromadd.replace("'", "''"), rtoadd.replace("'", "''"), interpolationtype.replace("'", "''"), name.replace("'", "''"), county.replace("'", "''"), zipr.replace("'", "''") ) )
|
||||
|
||||
if left:
|
||||
id += 1
|
||||
if ltofromint:
|
||||
if left:
|
||||
id += 1
|
||||
if ltofromint:
|
||||
if (lfromint % 2) == 0 and (ltoint % 2) == 0:
|
||||
if separated == "Y":
|
||||
if separated == "Y":
|
||||
interpolationtype = "even";
|
||||
elif rtofromint and (rfromint % 2) == 1 and (rtoint % 2) == 1:
|
||||
elif rtofromint and (rfromint % 2) == 1 and (rtoint % 2) == 1:
|
||||
interpolationtype = "even";
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
|
||||
elif (lfromint % 2) == 1 and (ltoint % 2) == 1:
|
||||
if separated == "Y":
|
||||
if separated == "Y":
|
||||
interpolationtype = "odd";
|
||||
elif rtofromint and (rfromint %2 ) == 0 and (rtoint % 2) == 0:
|
||||
elif rtofromint and (rfromint %2 ) == 0 and (rtoint % 2) == 0:
|
||||
interpolationtype = "odd";
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
else:
|
||||
else:
|
||||
interpolationtype = "all";
|
||||
ret.append( "select tigger_create_interpolation(ST_GeomFromText('LINESTRING(%s)',4326), '%s', '%s', '%s', '%s', '%s', '%s');" %
|
||||
( ",".join(llinestring), lfromadd.replace("'", "''"), ltoadd.replace("'", "''"), interpolationtype.replace("'", "''"), name.replace("'", "''"), county.replace("'", "''"), zipl.replace("'", "''") ) )
|
||||
@@ -4023,7 +4025,7 @@ def compile_waylist( parsed_gisdata, blank_way_id ):
|
||||
#Group by iSource:way_id
|
||||
for geom, tags in parsed_gisdata:
|
||||
way_key = tags.copy()
|
||||
way_key = ( way_key[iSource + ':way_id'], tuple( [(k,v) for k,v in way_key.iteritems()] ) )
|
||||
way_key = ( way_key[iSource + ':way_id'], tuple( [(k,v) for k,v in way_key.items()] ) )
|
||||
|
||||
if way_key not in waylist:
|
||||
waylist[way_key] = []
|
||||
@@ -4031,7 +4033,7 @@ def compile_waylist( parsed_gisdata, blank_way_id ):
|
||||
waylist[way_key].append( geom )
|
||||
|
||||
ret = {}
|
||||
for (way_id, way_key), segments in waylist.iteritems():
|
||||
for (way_id, way_key), segments in waylist.items():
|
||||
|
||||
if way_id != blank_way_id:
|
||||
ret[way_key] = glom_all( segments )
|
||||
@@ -4047,42 +4049,42 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
|
||||
import_guid = time.strftime( '%Y%m%d%H%M%S' )
|
||||
|
||||
print "parsing shpfile"
|
||||
print("parsing shpfile")
|
||||
parsed_features = parse_shp_for_osm( shp_filename )
|
||||
|
||||
print "compiling nodelist"
|
||||
print("compiling nodelist")
|
||||
i, nodelist = compile_nodelist( parsed_features )
|
||||
|
||||
print "compiling waylist"
|
||||
print("compiling waylist")
|
||||
waylist = compile_waylist( parsed_features, blank_way_id )
|
||||
|
||||
filenumber = 1
|
||||
objectcount = 0
|
||||
seen = {}
|
||||
|
||||
print "preparing address ways"
|
||||
print("preparing address ways")
|
||||
ret = addressways(waylist, nodelist, i)
|
||||
osm_filename = "%s%d.osm" % (base_filename, filenumber)
|
||||
print "writing %s" %osm_filename
|
||||
print("writing %s" %osm_filename)
|
||||
fp = open( osm_filename, "w" )
|
||||
fp.write( "\n".join( ret ) )
|
||||
fp.close()
|
||||
filenumber += 1
|
||||
|
||||
|
||||
print "constructing osm xml file"
|
||||
print("constructing osm xml file")
|
||||
ret = []
|
||||
ret.append( "<?xml version='1.0' encoding='UTF-8'?>" )
|
||||
ret.append( "<osm version='0.6' generator='shape_to_osm.py'>" )
|
||||
|
||||
for waykey, segments in waylist.iteritems():
|
||||
for waykey, segments in waylist.items():
|
||||
for segment in segments:
|
||||
#write the nodes
|
||||
#write the nodes
|
||||
for point in segment:
|
||||
id, (lat, lon) = nodelist[ round_point( point ) ]
|
||||
if id not in seen:
|
||||
seen[id] = True
|
||||
#write node
|
||||
#write node
|
||||
ret.append( " <node id='-%d' action='create' visible='true' lat='%f' lon='%f' >" % (id, lat, lon) )
|
||||
ret.append( " </node>" )
|
||||
objectcount += 1
|
||||
@@ -4090,7 +4092,7 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
pass
|
||||
#print "Skipping node %d" %id
|
||||
|
||||
#write the way
|
||||
#write the way
|
||||
ret.append( " <way id='-%d' action='create' visible='true'>" % i )
|
||||
|
||||
ids = [ nodelist[ round_point( point ) ][0] for point in segment ]
|
||||
@@ -4099,7 +4101,7 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
for id in ids:
|
||||
count += 1
|
||||
ret.append( " <nd ref='-%d' />" % id )
|
||||
if (count % Max_Waylength == 0) and (count != len(ids)): #Split the way
|
||||
if (count % Max_Waylength == 0) and (count != len(ids)): #Split the way
|
||||
for k, v in waykey:
|
||||
ret.append( " <tag k=\"%s\" v=\"%s\" />" % (k, escape(str(v))) )
|
||||
ret.append( " <tag k=\"source\" v=\"%s_import_v%s_%s\" />" % (iSource, VERSION, import_guid) )
|
||||
@@ -4107,7 +4109,7 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
|
||||
ret.append( " </way>" )
|
||||
objectcount += 1
|
||||
i += 1
|
||||
i += 1
|
||||
ret.append( " <way id='-%d' action='create' visible='true'>" % i )
|
||||
ret.append( " <nd ref='-%d' />" % id )
|
||||
|
||||
@@ -4121,10 +4123,10 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
|
||||
i += 1
|
||||
|
||||
if objectcount > maxNodes: #Write a file
|
||||
if objectcount > maxNodes: #Write a file
|
||||
ret.append( "</osm>" )
|
||||
osm_filename = "%s%d.osm" % (base_filename, filenumber)
|
||||
print "writing %s" %osm_filename
|
||||
print("writing %s" %osm_filename)
|
||||
fp = open( osm_filename, "w" )
|
||||
fp.write( "\n".join( ret ) )
|
||||
fp.close()
|
||||
@@ -4139,7 +4141,7 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
ret.append( "</osm>" )
|
||||
|
||||
osm_filename = "%s%d.osm" % (base_filename, filenumber)
|
||||
print "writing %s" %osm_filename
|
||||
print("writing %s" %osm_filename)
|
||||
fp = open( osm_filename, "w" )
|
||||
fp.write( "\n".join( ret ) )
|
||||
fp.close()
|
||||
@@ -4147,7 +4149,7 @@ def shape_to_osm( shp_filename, base_filename, blank_way_id ):
|
||||
if __name__ == '__main__':
|
||||
import sys, os.path
|
||||
if len(sys.argv) < 2:
|
||||
print "%s filename.shp [filename.osm]" % sys.argv[0]
|
||||
print("%s filename.shp [filename.osm]" % sys.argv[0])
|
||||
sys.exit()
|
||||
shape = sys.argv[1]
|
||||
if len(sys.argv) > 2:
|
||||
@@ -4155,6 +4157,6 @@ if __name__ == '__main__':
|
||||
else:
|
||||
osm = shape[0:-4] + ".osm"
|
||||
id = "1.shp"
|
||||
# Left over from massGIS unknown usage, but works fine hardcoded to "1.shp" which was the valu on a test of the actual mass data,
|
||||
#id = os.path.basename(shape).split("_")[-1]
|
||||
# Left over from massGIS unknown usage, but works fine hardcoded to "1.shp" which was the valu on a test of the actual mass data,
|
||||
#id = os.path.basename(shape).split("_")[-1]
|
||||
shape_to_osm( shape, osm, id )
|
||||
|
||||
@@ -54,15 +54,13 @@
|
||||
// Lock to prevent multiple copies running
|
||||
if (exec('/bin/ps uww | grep '.basename(__FILE__).' | grep -v /dev/null | grep -v grep -c', $aOutput2, $iResult) > 1)
|
||||
{
|
||||
echo "Copy already running\n";
|
||||
exit;
|
||||
fail("Copy already running\n");
|
||||
}
|
||||
if (!isset($aResult['max-load'])) $aResult['max-load'] = 1.9;
|
||||
if (!isset($aResult['max-blocking'])) $aResult['max-blocking'] = 3;
|
||||
if (getBlockingProcesses() > $aResult['max-blocking'])
|
||||
{
|
||||
echo "Too many blocking processes for import\n";
|
||||
exit;
|
||||
fail("Too many blocking processes for import\n");
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -83,7 +81,7 @@
|
||||
$iCacheMemory = getCacheMemoryMB();
|
||||
echo "WARNING: resetting cache memory to $iCacheMemory\n";
|
||||
}
|
||||
$sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
|
||||
$sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
|
||||
if (!is_null(CONST_Osm2pgsql_Flatnode_File))
|
||||
{
|
||||
$sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
|
||||
@@ -120,8 +118,7 @@
|
||||
$sNextFile = $aResult['import-diff'];
|
||||
if (!file_exists($sNextFile))
|
||||
{
|
||||
echo "Cannot open $sNextFile\n";
|
||||
exit;
|
||||
fail("Cannot open $sNextFile\n");
|
||||
}
|
||||
// Don't update the import status - we don't know what this file contains
|
||||
$sUpdateSQL = 'update import_status set lastimportdate = now() where false';
|
||||
@@ -137,8 +134,7 @@
|
||||
|
||||
if ($iErrorLevel)
|
||||
{
|
||||
echo "Error from osm2pgsql, $iErrorLevel\n";
|
||||
exit;
|
||||
fail("Error from osm2pgsql, $iErrorLevel\n");
|
||||
}
|
||||
|
||||
// Move the date onwards
|
||||
@@ -205,8 +201,7 @@
|
||||
exec($sCMD, $sJunk, $iErrorLevel);
|
||||
if ($iErrorLevel)
|
||||
{
|
||||
echo "Error converting osm to osc, osmosis returned: $iErrorLevel\n";
|
||||
exit;
|
||||
fail("Error converting osm to osc, osmosis returned: $iErrorLevel\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -221,8 +216,7 @@
|
||||
$hProc = proc_open($sCMD, $aSpec, $aPipes);
|
||||
if (!is_resource($hProc))
|
||||
{
|
||||
echo "Error converting osm to osc, osmosis failed\n";
|
||||
exit;
|
||||
fail("Error converting osm to osc, osmosis failed\n");
|
||||
}
|
||||
fwrite($aPipes[0], $sModifyXMLstr);
|
||||
fclose($aPipes[0]);
|
||||
@@ -237,7 +231,7 @@
|
||||
echo "Error converting osm to osc, osmosis returned: $iError\n";
|
||||
echo $sOut;
|
||||
echo $sErrors;
|
||||
exit;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,8 +241,7 @@
|
||||
exec($sCMD, $sJunk, $iErrorLevel);
|
||||
if ($iErrorLevel)
|
||||
{
|
||||
echo "osm2pgsql exited with error level $iErrorLevel\n";
|
||||
exit;
|
||||
fail("osm2pgsql exited with error level $iErrorLevel\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,8 +250,7 @@
|
||||
|
||||
$pgver = (float) CONST_Postgresql_Version;
|
||||
if ($pgver < 9.3) {
|
||||
echo "ERROR: deduplicate is only currently supported in postgresql 9.3";
|
||||
exit;
|
||||
fail("ERROR: deduplicate is only currently supported in postgresql 9.3");
|
||||
}
|
||||
|
||||
$oDB =& getDB();
|
||||
@@ -281,7 +273,7 @@
|
||||
if (PEAR::isError($aTokenSet))
|
||||
{
|
||||
var_dump($aTokenSet, $sSQL);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$aKeep = array_shift($aTokenSet);
|
||||
@@ -297,7 +289,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$sSQL = "update search_name set";
|
||||
@@ -307,7 +299,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$sSQL = "update location_area_country set";
|
||||
@@ -317,7 +309,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
foreach ($aPartitions as $sPartition)
|
||||
@@ -329,7 +321,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$sSQL = "update location_area_country set";
|
||||
@@ -339,7 +331,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +340,7 @@
|
||||
if (PEAR::isError($x))
|
||||
{
|
||||
var_dump($x);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,8 +356,7 @@
|
||||
{
|
||||
|
||||
if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
|
||||
echo "Error: Update interval too low for download.geofabrik.de. Please check install documentation (http://wiki.openstreetmap.org/wiki/Nominatim/Installation#Updates)\n";
|
||||
exit;
|
||||
fail("Error: Update interval too low for download.geofabrik.de. Please check install documentation (http://wiki.openstreetmap.org/wiki/Nominatim/Installation#Updates)\n");
|
||||
}
|
||||
|
||||
$sImportFile = CONST_BasePath.'/data/osmosischange.osc';
|
||||
@@ -527,7 +518,7 @@
|
||||
|
||||
$fDuration = time() - $fStartTime;
|
||||
echo date('Y-m-d H:i:s')." Completed all for $sBatchEnd in ".round($fDuration/60,2)." minutes\n";
|
||||
if (!$aResult['import-osmosis-all']) exit;
|
||||
if (!$aResult['import-osmosis-all']) exit(0);
|
||||
|
||||
if ( CONST_Replication_Update_Interval > 60 )
|
||||
{
|
||||
@@ -549,7 +540,7 @@
|
||||
if (PEAR::isError($iNPIID))
|
||||
{
|
||||
var_dump($iNPIID);
|
||||
exit;
|
||||
exit(1);
|
||||
}
|
||||
$sConfigDirectory = CONST_BasePath.'/settings';
|
||||
$sCMDImportTemplate = $sBasePath.'/nominatim/nominatim -d gazetteer -P 5433 -I -T '.$sBasePath.'/nominatim/partitionedtags.def -F ';
|
||||
@@ -580,8 +571,7 @@
|
||||
exec($sCMDImport, $sJunk, $iErrorLevel);
|
||||
if ($iErrorLevel)
|
||||
{
|
||||
echo "Error: $iErrorLevel\n";
|
||||
exit;
|
||||
fail("Error: $iErrorLevel\n");
|
||||
}
|
||||
$sBatchEnd = $iNPIID;
|
||||
echo "Completed for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
|
||||
|
||||
107
vagrant/centos-7-provision.sh
Normal file
107
vagrant/centos-7-provision.sh
Normal file
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script sets up a Nominatim installation on a CentOS 7 box.
|
||||
#
|
||||
# For more detailed CentOS installation instructions see also
|
||||
# http://wiki.openstreetmap.org/wiki/Nominatim/Installation_on_CentOS
|
||||
|
||||
## Part 1: System preparation
|
||||
|
||||
## During 'vagrant provision' this script runs as root and the current
|
||||
## directory is '/root'
|
||||
USERNAME=vagrant
|
||||
|
||||
yum update -y
|
||||
yum install -y epel-release
|
||||
|
||||
yum install -y postgresql-server postgresql-contrib postgresql-devel postgis postgis-utils \
|
||||
make automake gcc gcc-c++ libtool policycoreutils-python \
|
||||
php-pgsql php php-pear php-pear-DB libpqxx-devel proj-epsg \
|
||||
bzip2-devel proj-devel geos-devel libxml2-devel boost-devel \
|
||||
expat-devel zlib-devel
|
||||
|
||||
# Create a cluster and start up postgresql.
|
||||
postgresql-setup initdb
|
||||
systemctl enable postgresql
|
||||
systemctl start postgresql
|
||||
|
||||
# We leave postgresql in its default configuration here. This is only
|
||||
# suitable for small extracts.
|
||||
|
||||
# Create the necessary postgres users.
|
||||
sudo -u postgres createuser -s vagrant
|
||||
sudo -u postgres createuser apache
|
||||
|
||||
# Create the website directory.
|
||||
mkdir -m 755 /var/www/html/nominatim
|
||||
chown vagrant /var/www/html/nominatim
|
||||
|
||||
# Set up the necessary rights on SELinux.
|
||||
semanage fcontext -a -t httpd_sys_content_t "/home/vagrant/Nominatim/(website|lib|settings)(/.*)?"
|
||||
semanage fcontext -a -t lib_t "/home/vagrant/Nominatim/module/nominatim.so"
|
||||
semanage port -a -t http_port_t -p tcp 8089
|
||||
restorecon -R -v /home/vagrant/Nominatim
|
||||
|
||||
# Configure apache site.
|
||||
echo '
|
||||
Listen 8089
|
||||
<VirtualHost *:8089>
|
||||
# DirectoryIndex index.html
|
||||
# ErrorDocument 403 /index.html
|
||||
|
||||
DocumentRoot "/var/www/html/"
|
||||
|
||||
<Directory "/var/www/html/nominatim/">
|
||||
Options FollowSymLinks MultiViews
|
||||
AddType text/html .php
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
' | sudo tee /etc/httpd/conf.d/nominatim.conf > /dev/null
|
||||
|
||||
# Restart apache to enable the site configuration.
|
||||
systemctl enable httpd
|
||||
systemctl restart httpd
|
||||
|
||||
## Part 2: Nominatim installaion
|
||||
|
||||
# now ideally login as $USERNAME and continue
|
||||
cd /home/$USERNAME
|
||||
|
||||
# If the Nominatim source is not being shared with the host, check out source.
|
||||
if [ ! -d "Nominatim" ]; then
|
||||
yum install -y git
|
||||
sudo -u $USERNAME git clone --recursive https://github.com/twain47/Nominatim.git
|
||||
fi
|
||||
|
||||
# Configure and compile the source.
|
||||
cd Nominatim
|
||||
sudo -u $USERNAME ./autogen.sh
|
||||
sudo -u $USERNAME ./configure
|
||||
sudo -u $USERNAME make
|
||||
|
||||
# Make sure that postgres has access to the nominatim library.
|
||||
chmod +x /home/$USERNAME
|
||||
chmod +x ./
|
||||
chmod +x ./module
|
||||
|
||||
# Create customized settings suitable for this VM installation.
|
||||
LOCALSETTINGS_FILE='settings/local.php'
|
||||
if [[ -e "$LOCALSETTINGS_FILE" ]]; then
|
||||
echo "$LOCALSETTINGS_FILE already exist, writing to settings/local-vagrant.php instead."
|
||||
LOCALSETTINGS_FILE='settings/local-vagrant.php'
|
||||
fi
|
||||
|
||||
IP=localhost
|
||||
echo "<?php
|
||||
// General settings
|
||||
@define('CONST_Database_DSN', 'pgsql://@/nominatim');
|
||||
// Paths
|
||||
@define('CONST_Postgresql_Version', '9.2');
|
||||
@define('CONST_Postgis_Version', '2.0');
|
||||
@define('CONST_Database_Web_User', 'apache');
|
||||
// Website settings
|
||||
@define('CONST_Website_BaseURL', 'http://$IP:8089/nominatim/');
|
||||
" > $LOCALSETTINGS_FILE
|
||||
|
||||
# Install the web interface.
|
||||
sudo -u $USERNAME ./utils/setup.php --create-website /var/www/html/nominatim
|
||||
174
vagrant/ubuntu-trusty-provision.sh
Executable file
174
vagrant/ubuntu-trusty-provision.sh
Executable file
@@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script sets up a Nominatim installation on a Ubuntu box.
|
||||
#
|
||||
# For more detailed installation instructions see also
|
||||
# http://wiki.openstreetmap.org/wiki/Nominatim/Installation
|
||||
|
||||
## Part 1: System preparation
|
||||
|
||||
## During 'vagrant provision' this script runs as root and the current
|
||||
## directory is '/root'
|
||||
USERNAME=vagrant
|
||||
|
||||
###
|
||||
### maybe create ubuntu user
|
||||
###
|
||||
|
||||
# if [[ ! `id -u $USERNAME` ]]; then
|
||||
# useradd $USERNAME --create-home --shell /bin/bash
|
||||
#
|
||||
# # give sudo power
|
||||
# echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/99-$USERNAME-user
|
||||
# chmod 0440 /etc/sudoers.d/99-$USERNAME-user
|
||||
# service sudo restart
|
||||
#
|
||||
# # add basic .profile
|
||||
# cp -r .ssh .profile .bashrc /home/$USERNAME/
|
||||
# chown -R $USERNAME /home/$USERNAME/.*
|
||||
# chgrp -R $USERNAME /home/$USERNAME/.*
|
||||
#
|
||||
# # now ideally login as $USERNAME and continue
|
||||
# su $USERNAME -l
|
||||
# fi
|
||||
|
||||
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get upgrade -y
|
||||
sudo apt-get install -y build-essential libgeos-dev libpq-dev libbz2-dev \
|
||||
libtool automake libproj-dev libboost-dev libboost-system-dev \
|
||||
libboost-filesystem-dev libboost-thread-dev libexpat-dev
|
||||
sudo apt-get autoremove -y
|
||||
|
||||
# get arrow-keys working in terminal (e.g. editing in vi)
|
||||
echo 'stty sane' >> ~/.bash_profile
|
||||
echo 'export TERM=linux' >> ~/.bash_profile
|
||||
source ~/.bash_profile
|
||||
|
||||
|
||||
###
|
||||
### PostgreSQL 9.3 + PostGIS 2.1
|
||||
###
|
||||
|
||||
sudo apt-get install -y postgresql-9.3-postgis-2.1 postgresql-contrib-9.3 postgresql-server-dev-9.3
|
||||
# already included: proj-bin libgeos-dev
|
||||
|
||||
# make sure OS-authenticated users (e.g. $USERNAME) can access
|
||||
sudo sed -i "s/ident/trust/" /etc/postgresql/9.3/main/pg_hba.conf
|
||||
sudo sed -i "s/md5/trust/" /etc/postgresql/9.3/main/pg_hba.conf
|
||||
sudo sed -i "s/peer/trust/" /etc/postgresql/9.3/main/pg_hba.conf
|
||||
sudo /etc/init.d/postgresql restart
|
||||
|
||||
# creates the role
|
||||
sudo -u postgres createuser -s $USERNAME
|
||||
|
||||
|
||||
|
||||
###
|
||||
### PHP for frontend
|
||||
###
|
||||
sudo apt-get install -y php5 php5-pgsql php-pear php-db
|
||||
|
||||
|
||||
# get rid of some warning
|
||||
# where is the ini file? 'php --ini'
|
||||
echo "date.timezone = 'Etc/UTC'" | sudo tee /etc/php5/cli/conf.d/99-timezone.ini > /dev/null
|
||||
|
||||
|
||||
|
||||
###
|
||||
### Nominatim
|
||||
###
|
||||
sudo apt-get install -y libgeos-c1 libgeos++-dev libxml2-dev
|
||||
|
||||
## Part 2: Nominatim installaion
|
||||
|
||||
# now ideally login as $USERNAME and continue
|
||||
cd /home/$USERNAME
|
||||
|
||||
# If the Nominatim source is not being shared with the host, check out source.
|
||||
if [ ! -d "Nominatim" ]; then
|
||||
sudo apt-get install -y git
|
||||
sudo -u $USERNAME git clone --recursive https://github.com/twain47/Nominatim.git
|
||||
fi
|
||||
|
||||
cd Nominatim
|
||||
|
||||
sudo -u $USERNAME ./autogen.sh
|
||||
sudo -u $USERNAME ./configure
|
||||
sudo -u $USERNAME make
|
||||
chmod +x ./
|
||||
chmod +x ./module
|
||||
|
||||
|
||||
LOCALSETTINGS_FILE='settings/local.php'
|
||||
if [[ -e "$LOCALSETTINGS_FILE" ]]; then
|
||||
echo "$LOCALSETTINGS_FILE already exist, writing to settings/local-vagrant.php instead."
|
||||
LOCALSETTINGS_FILE='settings/local-vagrant.php'
|
||||
fi
|
||||
|
||||
# IP=`curl -s http://bot.whatismyipaddress.com`
|
||||
IP=localhost
|
||||
echo "<?php
|
||||
// General settings
|
||||
@define('CONST_Database_DSN', 'pgsql://@/nominatim');
|
||||
// Paths
|
||||
@define('CONST_Postgresql_Version', '9.3');
|
||||
@define('CONST_Postgis_Version', '2.1');
|
||||
// Website settings
|
||||
@define('CONST_Website_BaseURL', 'http://$IP:8089/nominatim/');
|
||||
" > $LOCALSETTINGS_FILE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
###
|
||||
### Setup Apache/website
|
||||
###
|
||||
|
||||
sudo -u postgres createuser -SDR www-data
|
||||
|
||||
echo '
|
||||
Listen 8089
|
||||
<VirtualHost *:8089>
|
||||
# DirectoryIndex index.html
|
||||
# ErrorDocument 403 /index.html
|
||||
|
||||
DocumentRoot "/var/www/"
|
||||
|
||||
<Directory "/var/www/nominatim/">
|
||||
Options FollowSymLinks MultiViews
|
||||
AddType text/html .php
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
' | sudo tee /etc/apache2/sites-enabled/nominatim.conf > /dev/null
|
||||
|
||||
|
||||
apache2ctl graceful
|
||||
|
||||
|
||||
mkdir -m 755 /var/www/nominatim
|
||||
chown $USERNAME /var/www/nominatim
|
||||
sudo -u $USERNAME ./utils/setup.php --create-website /var/www/nominatim
|
||||
|
||||
|
||||
# if you get 'permission denied for relation word', then try
|
||||
# GRANT usage ON SCHEMA public TO "www-data";
|
||||
# GRANT SELECT ON ALL TABLES IN SCHEMA public TO "www-data";
|
||||
|
||||
##
|
||||
## Test suite (Python)
|
||||
## https://github.com/twain47/Nominatim/tree/master/tests
|
||||
##
|
||||
apt-get install -y python-dev python-pip python-Levenshtein python-shapely \
|
||||
python-psycopg2 tidy python-nose python-tidylib
|
||||
pip install lettuce==0.2.18 six==1.7 haversine
|
||||
|
||||
## Test suite (PHP)
|
||||
## https://github.com/twain47/Nominatim/tree/master/tests-php
|
||||
apt-get install -y phpunit
|
||||
|
||||
|
||||
14
website/css/bootstrap-theme.min.css
vendored
Executable file
14
website/css/bootstrap-theme.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
14
website/css/bootstrap.min.css
vendored
Executable file
14
website/css/bootstrap.min.css
vendored
Executable file
File diff suppressed because one or more lines are too long
31
website/css/common.css
Normal file
31
website/css/common.css
Normal file
@@ -0,0 +1,31 @@
|
||||
header {
|
||||
width: 100%;
|
||||
padding: 5px 15px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
header .brand {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
header .brand a:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
header .brand h1 {
|
||||
display: inline;
|
||||
font-size: 1.5em;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
header .brand > img {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
header #last-updated {
|
||||
font-size: 0.7em;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1,12 +1,34 @@
|
||||
body {
|
||||
margin:0px;
|
||||
padding:16px;
|
||||
background:#ffffff;
|
||||
height: 100%;
|
||||
font: normal 12px/15px arial,sans-serif;
|
||||
h1 {
|
||||
margin: 10px 0;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.line{
|
||||
margin-left:20px;
|
||||
h2 {
|
||||
font-size: 2em;
|
||||
padding-left: 8px;
|
||||
background-color: white;
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
tr.all-columns {
|
||||
background-color: white !important;
|
||||
border: none;
|
||||
}
|
||||
tr.all-columns td {
|
||||
border-top: none !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
}
|
||||
.table td {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.table>thead>tr>td, .table>tbody>tr>td {
|
||||
padding: 2px 8px;
|
||||
}
|
||||
.name{
|
||||
font-weight: bold;
|
||||
@@ -18,9 +40,22 @@ body {
|
||||
color:#800;
|
||||
}
|
||||
#map {
|
||||
width:500px;
|
||||
height:500px;
|
||||
border: 2px solid #666;
|
||||
float: right;
|
||||
width:100%;
|
||||
height:300px;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
#mapicon {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2em 0;
|
||||
font-size: 0.8em;
|
||||
clear: both;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
footer p {
|
||||
margin: 1em;
|
||||
}
|
||||
479
website/css/leaflet.css
Normal file
479
website/css/leaflet.css
Normal file
@@ -0,0 +1,479 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-map-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-pane,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-overlay-pane,
|
||||
.leaflet-shadow-pane,
|
||||
.leaflet-marker-pane,
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-overlay-pane svg,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container img {
|
||||
max-width: none !important;
|
||||
}
|
||||
/* stupid Android 2 doesn't understand "max-width: none" properly */
|
||||
.leaflet-container img.leaflet-image-layer {
|
||||
max-width: 15000px !important;
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-tile-pane { z-index: 2; }
|
||||
.leaflet-objects-pane { z-index: 3; }
|
||||
.leaflet-overlay-pane { z-index: 4; }
|
||||
.leaflet-shadow-pane { z-index: 5; }
|
||||
.leaflet-marker-pane { z-index: 6; }
|
||||
.leaflet-popup-pane { z-index: 7; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 7;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile,
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-tile-loaded,
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile,
|
||||
.leaflet-touching .leaflet-zoom-animated {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-container {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-container,
|
||||
.leaflet-dragging .leaflet-clickable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
.leaflet-control-zoom-out {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in {
|
||||
font-size: 22px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
margin: 0 auto;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
@@ -1,166 +1,141 @@
|
||||
* {-moz-box-sizing: border-box;}
|
||||
body {
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
overflow: hidden;
|
||||
background:#ffffff;
|
||||
height: 100%;
|
||||
font: normal 12px/15px arial,sans-serif;
|
||||
|
||||
|
||||
form {
|
||||
width: 100%;
|
||||
padding: 1em 15px;
|
||||
}
|
||||
#seachheader {
|
||||
position:absolute;
|
||||
z-index:5;
|
||||
top:0px;
|
||||
left:0px;
|
||||
width:100%;
|
||||
height:38px;
|
||||
background:#F0F7FF;
|
||||
border-bottom: 2px solid #75ADFF;
|
||||
form #q {
|
||||
min-width: 500px;
|
||||
}
|
||||
#q {
|
||||
width:300px;
|
||||
@media (max-width: 850px) {
|
||||
form #q {
|
||||
min-width: 400px;
|
||||
}
|
||||
#seachheaderfade1, #seachheaderfade2, #seachheaderfade3, #seachheaderfade4{
|
||||
position:absolute;
|
||||
z-index:4;
|
||||
top:0px;
|
||||
left:0px;
|
||||
width:100%;
|
||||
opacity: 0.15;
|
||||
filter: alpha(opacity = 15);
|
||||
background:#000000;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
#seachheaderfade1{
|
||||
height:39px;
|
||||
form .checkbox-inline {
|
||||
margin-left: 10px;
|
||||
}
|
||||
#seachheaderfade2{
|
||||
height:40px;
|
||||
}
|
||||
#seachheaderfade3{
|
||||
height:41px;
|
||||
}
|
||||
#seachheaderfade4{
|
||||
height:42px;
|
||||
}
|
||||
#searchresultsfade1, #searchresultsfade2, #searchresultsfade3, #searchresultsfade4 {
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
top:0px;
|
||||
left:200px;
|
||||
height: 100%;
|
||||
opacity: 0.2;
|
||||
filter: alpha(opacity = 20);
|
||||
background:#ffffff;
|
||||
border: 1px solid #ffffff;
|
||||
}
|
||||
#searchresultsfade1{
|
||||
width:1px;
|
||||
}
|
||||
#searchresultsfade2{
|
||||
width:2px;
|
||||
}
|
||||
#searchresultsfade3{
|
||||
width:3px;
|
||||
}
|
||||
#searchresultsfade4{
|
||||
width:4px;
|
||||
form label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#searchresults{
|
||||
position:absolute;
|
||||
z-index:3;
|
||||
top:41px;
|
||||
width:200px;
|
||||
.search-type-link {
|
||||
display: inline;
|
||||
margin-right: 2em;
|
||||
position: absolute;
|
||||
right: 0
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 25%;
|
||||
padding: 15px;
|
||||
padding-top: 0;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
#map-wrapper {
|
||||
position: relative;
|
||||
min-height: 700px;
|
||||
width: 75%;
|
||||
padding-right: 20px;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 100%;
|
||||
background:#ffffff;
|
||||
border: 1px solid #ffffff;
|
||||
overflow: auto;
|
||||
}
|
||||
#map{
|
||||
position:absolute;
|
||||
z-index:1;
|
||||
top:38px;
|
||||
left:200px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
min-height: 700px;
|
||||
background:#eee;
|
||||
}
|
||||
#report{
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
top:38px;
|
||||
left:200px;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:#eee;
|
||||
font: normal 12px/15px arial,sans-serif;
|
||||
padding:20px;
|
||||
}
|
||||
#report table {
|
||||
margin-left:20px;
|
||||
}
|
||||
#report th {
|
||||
vertical-align:top;
|
||||
text-align:left;
|
||||
}
|
||||
#report td.button {
|
||||
text-align:right;
|
||||
|
||||
#map-position {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 20px;
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
font-size: 11px;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.result {
|
||||
margin:5px;
|
||||
margin-bottom:0px;
|
||||
padding:2px;
|
||||
padding-left:4px;
|
||||
padding-right:4px;
|
||||
border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
font-size: 0.8em;
|
||||
margin: 5px;
|
||||
margin-top:0px;
|
||||
padding: 4px 8px;
|
||||
border-radius: 2px;
|
||||
background:#F0F7FF;
|
||||
border: 2px solid #D7E7FF;
|
||||
font: normal 12px/15px arial,sans-serif;
|
||||
cursor:pointer;
|
||||
}
|
||||
.result img{
|
||||
float:right;
|
||||
}
|
||||
.result .latlon{
|
||||
display: none;
|
||||
}
|
||||
.result .place_id{
|
||||
display: none;
|
||||
}
|
||||
.result .type{
|
||||
color: #999;
|
||||
text-align:center;
|
||||
font: normal 9px/10px arial,sans-serif;
|
||||
padding-top:4px;
|
||||
}
|
||||
.result .details, .result .details a{
|
||||
color: #999;
|
||||
text-align:center;
|
||||
font: normal 9px/10px arial,sans-serif;
|
||||
padding-top:4px;
|
||||
}
|
||||
.noresults{
|
||||
color: #000;
|
||||
text-align:center;
|
||||
font: normal 12px arial,sans-serif;
|
||||
padding-top:4px;
|
||||
}
|
||||
.more{
|
||||
color: #ccc;
|
||||
text-align:center;
|
||||
padding-top:4px;
|
||||
}
|
||||
.disclaimer{
|
||||
color: #ccc;
|
||||
text-align:center;
|
||||
font: normal 9px/10px arial,sans-serif;
|
||||
padding-top:4px;
|
||||
}
|
||||
form{
|
||||
margin:0px;
|
||||
padding:0px;
|
||||
min-height: 5em;
|
||||
}
|
||||
|
||||
|
||||
.result.highlight {
|
||||
background-color: #D9E7F7;
|
||||
border-color: #9DB9E4;
|
||||
}
|
||||
.result.highlight .details {
|
||||
margin: 10px auto;
|
||||
display: block;
|
||||
max-width: 10em;
|
||||
}
|
||||
.result img{
|
||||
float: right;
|
||||
}
|
||||
.result .type{
|
||||
color: gray;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.result .details {
|
||||
display: none;
|
||||
}
|
||||
.noresults{
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.more{
|
||||
text-align:center;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2em 0;
|
||||
font-size: 0.8em;
|
||||
clear: both;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
footer p {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#content {
|
||||
top: 0;
|
||||
position: relative;
|
||||
}
|
||||
#map-wrapper {
|
||||
width: 100%;
|
||||
max-height: 300px;
|
||||
padding: 20px;
|
||||
}
|
||||
#map-position {
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
#map {
|
||||
height: 300px;
|
||||
}
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
}
|
||||
.search-button-group {
|
||||
display: inline
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
$_GET['place_id'] = $oDB->getOne("select place_id from placex where osm_type = '".$_GET['osmtype']."' and osm_id = ".(int)$_GET['osmid']." order by type = 'postcode' asc");
|
||||
|
||||
// Be nice about our error messages for broken geometry
|
||||
|
||||
if (!$_GET['place_id'])
|
||||
{
|
||||
$aPointDetails = $oDB->getRow("select osm_type, osm_id, errormessage, class, type, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom from import_polygon_error where osm_type = '".$_GET['osmtype']."' and osm_id = ".(int)$_GET['osmid']." order by updated desc limit 1");
|
||||
@@ -34,12 +35,18 @@
|
||||
$aPointDetails['error_x'] = $aMatches[1];
|
||||
$aPointDetails['error_y'] = $aMatches[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
$aPointDetails['error_x'] = 0;
|
||||
$aPointDetails['error_y'] = 0;
|
||||
}
|
||||
include(CONST_BasePath.'/lib/template/details-error-'.$sOutputFormat.'.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!isset($_GET['place_id']))
|
||||
{
|
||||
echo "Please select a place id";
|
||||
@@ -81,30 +88,46 @@
|
||||
// Get all alternative names (languages, etc)
|
||||
$sSQL = "select (each(name)).key,(each(name)).value from placex where place_id = $iPlaceID order by (each(name)).key";
|
||||
$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
|
||||
if (PEAR::isError($aPointDetails['aNames'])) // possible timeout
|
||||
{
|
||||
$aPointDetails['aNames'] = [];
|
||||
}
|
||||
|
||||
// Extra tags
|
||||
$sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = $iPlaceID order by (each(extratags)).key";
|
||||
$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
|
||||
if (PEAR::isError($aPointDetails['aExtraTags'])) // possible timeout
|
||||
{
|
||||
$aPointDetails['aExtraTags'] = [];
|
||||
}
|
||||
|
||||
// Address
|
||||
$aAddressLines = getAddressDetails($oDB, $sLanguagePrefArraySQL, $iPlaceID, $aPointDetails['country_code'], true);
|
||||
|
||||
// Linked places
|
||||
$sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_distance(geometry, placegeometry) as distance, ";
|
||||
$sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
|
||||
$sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
|
||||
$sSQL .= " from placex, (select geometry as placegeometry from placex where place_id = $iPlaceID) as x";
|
||||
$sSQL .= " from placex, (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
|
||||
$sSQL .= " where linked_place_id = $iPlaceID";
|
||||
$sSQL .= " order by rank_address asc,rank_search asc,get_name_by_language(name,$sLanguagePrefArraySQL),housenumber";
|
||||
$aLinkedLines = $oDB->getAll($sSQL);
|
||||
if (PEAR::isError($aLinkedLines)) // possible timeout
|
||||
{
|
||||
$aLinkedLines = [];
|
||||
}
|
||||
|
||||
// All places this is an imediate parent of
|
||||
$sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, st_distance(geometry, placegeometry) as distance, ";
|
||||
$sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
|
||||
$sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
|
||||
$sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
|
||||
$sSQL .= " where parent_place_id = $iPlaceID order by rank_address asc,rank_search asc limit 500) as obj,";
|
||||
$sSQL .= " (select geometry as placegeometry from placex where place_id = $iPlaceID) as x";
|
||||
$sSQL .= " (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
|
||||
$sSQL .= " order by rank_address asc,rank_search asc,localname,housenumber";
|
||||
$aParentOfLines = $oDB->getAll($sSQL);
|
||||
if (PEAR::isError($aParentOfLines)) // possible timeout
|
||||
{
|
||||
$aParentOfLines = [];
|
||||
}
|
||||
|
||||
$aPlaceSearchNameKeywords = false;
|
||||
$aPlaceSearchAddressKeywords = false;
|
||||
@@ -112,12 +135,36 @@
|
||||
{
|
||||
$sSQL = "select * from search_name where place_id = $iPlaceID";
|
||||
$aPlaceSearchName = $oDB->getRow($sSQL);
|
||||
if (PEAR::isError($aPlaceSearchName)) // possible timeout
|
||||
{
|
||||
$aPlaceSearchName = [];
|
||||
}
|
||||
|
||||
$sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['name_vector'],1,-1).")";
|
||||
$aPlaceSearchNameKeywords = $oDB->getAll($sSQL);
|
||||
if (PEAR::isError($aPlaceSearchNameKeywords)) // possible timeout
|
||||
{
|
||||
$aPlaceSearchNameKeywords = [];
|
||||
}
|
||||
|
||||
|
||||
$sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['nameaddress_vector'],1,-1).")";
|
||||
$aPlaceSearchAddressKeywords = $oDB->getAll($sSQL);
|
||||
if (PEAR::isError($aPlaceSearchAddressKeywords)) // possible timeout
|
||||
{
|
||||
$aPlaceSearchAddressKeywords = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
logEnd($oDB, $hLog, 1);
|
||||
|
||||
if ($sOutputFormat=='html')
|
||||
{
|
||||
$sDataDate = $oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1");
|
||||
$sTileURL = CONST_Map_Tile_URL;
|
||||
$sTileAttribution = CONST_Map_Tile_Attribution;
|
||||
}
|
||||
|
||||
|
||||
include(CONST_BasePath.'/lib/template/details-'.$sOutputFormat.'.php');
|
||||
|
||||
@@ -64,6 +64,13 @@
|
||||
$oPlaceLookup->setPlaceId($iPlaceID);
|
||||
|
||||
$aPlaceAddress = array_reverse($oPlaceLookup->getAddressDetails());
|
||||
|
||||
if (!sizeof($aPlaceAddress))
|
||||
{
|
||||
echo "Unknown place id.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$aBreadcrums = array();
|
||||
foreach($aPlaceAddress as $i => $aPlace)
|
||||
{
|
||||
|
||||
BIN
website/images/crosshair.png
Normal file
BIN
website/images/crosshair.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 140 B |
BIN
website/images/layers-2x.png
Normal file
BIN
website/images/layers-2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user