Compare commits

..

427 Commits

Author SHA1 Message Date
DennisSchiefer f7150057d5 slight version bump to 0.1.8.1 2012-09-18 12:02:43 +01:00
DennisSchiefer c3288528bc Merge remote-tracking branch 'origin/develop' 2012-09-18 12:01:37 +01:00
DennisSchiefer f1e935e904 Swedish translation thanks to Tobias Johansson 2012-09-18 11:47:08 +01:00
DennisSchiefer 72d5b60500 added comment 2012-09-17 15:26:46 +01:00
DennisSchiefer 621d2a6504 graceful decay if route names are not implemented in router engine 2012-09-17 15:19:58 +01:00
DennisSchiefer eefaabbd16 added route names in tooltips (remember to remove temporary names when
this goes live in the router)
2012-09-17 09:43:16 +01:00
DennisSchiefer 3d5f242398 error correction 2012-09-12 16:47:56 +01:00
DennisSchiefer 98ac1224cf corrected Turkish translation,
added Portuguese translation
2012-09-12 16:47:08 +01:00
DennisSchiefer 88fac9ab51 translations thanks to the EU Comenius Project
Necdet Varoglu (turkey)
Madalina Ionescu (romania)
2012-09-12 13:31:31 +01:00
DennisSchiefer be56bafdc4 romanian and turkish translation,
added to japanese translation
2012-09-12 13:18:26 +01:00
DennisSchiefer 21acdd90e0 corrected Nominatim link,
added incomplete Japanese translation
2012-09-10 07:16:33 +01:00
DennisSchiefer 891630bb4b remove highlight marker when switching alternatives 2012-09-03 15:44:18 +01:00
DennisSchiefer 2b8eefe238 updated Spanish translation 2012-09-03 08:44:11 +01:00
DennisSchiefer 54270f5169 when showing a highlight marker, respective description stays selected 2012-09-03 08:27:08 +01:00
DennisSchiefer ce1db933f3 added temporary marker when hovering over a route description 2012-09-03 08:02:18 +01:00
DennisSchiefer e9a31746b6 fixed order of tile servers for Chrome and IE 2012-08-31 15:11:39 +01:00
DennisSchiefer 22435f693d convenience method for changing marker tooltips 2012-08-31 14:50:22 +01:00
DennisSchiefer 71d0268642 updated readme 2012-08-31 14:41:39 +01:00
DennisSchiefer 35d2c6871f Merge remote-tracking branch 'github/master' 2012-08-31 14:32:59 +01:00
DennisSchiefer 9a7863f8d5 removed whitespaces 2012-08-31 14:31:03 +01:00
DennisSchiefer 716e5ed6b0 fix for engine selector size when changing languages 2012-08-31 14:24:35 +01:00
DennisSchiefer 8f4e10de2d Merge pull request #17 from DennisOSRM/patch-3
Typefix for automatic deploy script
2012-08-31 06:00:25 -07:00
Project OSRM 99b36e8f46 Typefix for automatic deploy script 2012-08-31 15:58:13 +03:00
DennisSchiefer d64fb6781c removed test routing engines for release 2012-08-31 08:17:05 +01:00
DennisSchiefer cdaef51b20 version push to 0.1.8 2012-08-31 07:41:01 +01:00
DennisSchiefer 40ad5a22ad styles for qrcode image 2012-08-31 07:34:37 +01:00
DennisSchiefer 54232645ae higher qrcode window 2012-08-31 07:34:12 +01:00
DennisSchiefer 618bb3ef70 bugfix so that HTML5 capable browsers use canvas 2012-08-31 07:22:57 +01:00
DennisSchiefer a83a3d125d adding QR codes 2012-08-30 16:50:59 +01:00
DennisSchiefer f2a4a02af8 bugfix for Leaflet bug 2012-08-30 15:46:08 +01:00
DennisSchiefer cdc98b2ad8 fixed bug with printing window 2012-08-30 15:13:36 +01:00
DennisSchiefer aee90bf530 added localization for qr code 2012-08-30 15:13:22 +01:00
DennisSchiefer db857166b2 fixed bug that mapping options were no longer localized 2012-08-30 07:59:27 +01:00
DennisSchiefer 0d13f1f6d7 bugfix for distance units 2012-08-28 12:29:22 +01:00
DennisSchiefer 65f53b6563 changed mouse cursor on layers control 2012-08-28 09:18:30 +01:00
DennisSchiefer d4c5725613 inactive buttons use default cursor 2012-08-28 09:09:43 +01:00
DennisSchiefer ab99ffc241 added OSRM layers control;
refactored checkboxes in mapping block
2012-08-28 08:57:14 +01:00
DennisSchiefer 794140711d - gui animations no longer trigger an onEndTransition event on loading
- refactored control management (handle is stored with map)
- refactored inactive control buttons (no background change)
- added localization strings for zooming and default search engine
- renaming: OSRM.MapView -> OSRM.Control.Map
2012-08-27 16:24:37 +01:00
DennisSchiefer 6dcea6d808 changed icons for locations and layers 2012-08-27 12:58:41 +01:00
DennisSchiefer c9f229fea8 Bulgarian translation thanks to Konstantin Delchev 2012-08-27 12:58:13 +01:00
DennisSchiefer d3d3ebb5de added new buttons for map zooming and requesting important locations 2012-08-27 10:27:19 +01:00
DennisSchiefer 94ad1003e9 bugfix to store shortest distance to route within the the closest
point no longer required
2012-08-24 14:16:50 +01:00
DennisSchiefer afb70126ad prevent drag after dragEnd bugfix no longer need 2012-08-24 14:03:06 +01:00
DennisSchiefer 532d7cb057 added switching between search engines
- works with different languages
- works with links

refactored selector code:
- changed method names
- changed method parameters (object -> id),
- added method to rename all options of dropdown menu

refactored distance format selector code:
- changed method names
- changed variable names
- changed how to init/select element/change language of dropdown menu

refactored maintenance notification overrides:
- changed names of default variables
2012-08-24 13:27:21 +01:00
DennisSchiefer e98afb46e7 removed new gui buttons again 2012-08-24 08:00:27 +01:00
DennisSchiefer f8779e479e temporary commit 2012-08-24 07:58:29 +01:00
DennisSchiefer e1cb34cf38 further restructuring of gui buttons 2012-08-23 17:08:55 +01:00
DennisSchiefer f2cd56b329 fixed bug with geocoder 2012-08-23 14:45:38 +01:00
DennisSchiefer 80d51683d4 first additions for multiple engine gui 2012-08-23 14:12:45 +01:00
DennisSchiefer ee8d04656d added function to zoom on user and translations 2012-08-23 07:55:25 +01:00
DennisSchiefer 3fc8c4309f added tooltip for gui boxes 2012-08-22 16:20:28 +01:00
DennisSchiefer 3f1c3e0923 moved gui version/timestamp to configuration box 2012-08-22 15:47:09 +01:00
DennisSchiefer 695ef4746b changed legal notice (added link to Project OSRM website thanks to the
kind request of a fellow OSM user)
2012-08-22 14:31:27 +01:00
DennisSchiefer 995466e89f raw image for new controls 2012-08-22 14:03:28 +01:00
DennisSchiefer 4f28b2fe69 changed sorting/filtering step of processing geocoder results:
relations are no longer skipped; boundaries are highest ranked;
duplicate locations are removed
2012-08-22 14:02:52 +01:00
DennisSchiefer 5498aa03a5 additional controls (temporary) 2012-08-22 13:16:16 +01:00
DennisSchiefer 60d236dd3e images for additional controls 2012-08-22 13:15:55 +01:00
DennisSchiefer f571b5c7e5 circumvent leaflet racing condition #918 by switching off animation
during initialization
2012-08-22 07:25:45 +01:00
DennisSchiefer 792404b311 changed cz -> cs 2012-08-14 17:22:41 +01:00
DennisSchiefer 862cde1056 fix for maps without attribution control 2012-08-14 17:16:04 +01:00
DennisSchiefer 71399daf00 added scale control 2012-08-14 16:51:24 +01:00
DennisSchiefer 320bbcfb20 Merge branch 'trial/multiple_servers' into trial/leaflet04 2012-08-14 15:37:05 +01:00
DennisSchiefer 4bb52cfe8c czech translation thanks to miszka999 2012-08-14 15:29:00 +01:00
DennisSchiefer 915baf57c3 corrected russian translation (direction 6, 8) 2012-08-14 15:15:42 +01:00
DennisSchiefer f31abcea80 fixed bugs with printing -> needed to recreate all objects in printing
window context
2012-08-14 15:13:33 +01:00
DennisSchiefer 3ab5a22890 fix for culture and icons 2012-08-14 13:46:46 +01:00
DennisSchiefer 5a2dd78694 removed old marker/icon classes 2012-08-14 12:39:47 +01:00
DennisSchiefer 6c2e391622 leaflet 0.4 compliant markers and icons 2012-08-14 12:39:26 +01:00
DennisSchiefer 9a6c6cd485 added routing_engine and routing_metric to describe the currently chosen
routing
2012-08-14 06:59:42 +01:00
DennisSchiefer ea84f774a7 fixed problem with using non L.LatLng objects 2012-08-13 16:12:41 +01:00
DennisSchiefer 5901b25e69 set dashArray for non-dashed lines 2012-08-13 15:03:48 +01:00
DennisSchiefer d9b0ab3d2e reenabled features;
removed no longer needed custom initialization of Control.Layers
2012-08-13 14:56:33 +01:00
DennisSchiefer f004a65db1 removed dashed polyine 2012-08-13 14:46:26 +01:00
DennisSchiefer b792d44b4e removed deprecated TileLayer.Bing 2012-08-13 13:29:36 +01:00
DennisSchiefer e8eb342434 finalized BingLayers;
added culture support outside of BingLayers.js
2012-08-13 13:29:03 +01:00
DennisSchiefer 0916e3f2e3 added new BingLayer code 2012-08-13 13:10:09 +01:00
DennisSchiefer 5f089e628b switched to leaflet0.4;
commented out most GUI
2012-08-13 13:04:26 +01:00
shiin de2e070dde remove one indirection from routing server url 2012-07-30 15:13:46 +02:00
shiin 8ecae7ef97 support for multiple routing servers 2012-07-30 15:06:15 +02:00
shiin ecd342224e notifications can be switched on/off in OSRM.config,
notifications can be localized
2012-07-30 14:40:56 +02:00
shiin 1f7a724ded added function to check whether a variable holds a number 2012-07-30 14:39:01 +02:00
DennisSchiefer ecd04188df fixed bug with giving a destination in the url 2012-07-16 13:31:41 +01:00
DennisSchiefer 71f55dc30a fix for old route links breaking 2012-07-10 15:40:09 +01:00
DennisSchiefer 1746946b70 changed notification time from 3min to 30min 2012-07-10 15:24:56 +01:00
DennisSchiefer 3746a25057 fixed bug with .class vs ["class"] 2012-07-10 14:44:33 +01:00
DennisSchiefer 17bfe95cd3 Russian translation (thanks to Barboska) 2012-07-09 09:38:32 +01:00
DennisSchiefer e90fe88cc0 added whitespaces to the tooltips for alternatives before the numbers 2012-07-06 11:50:25 +01:00
DennisSchiefer eba6330db1 removed backup file 2012-07-05 14:50:16 +01:00
DennisSchiefer a21aaf330e added backup to tooltip handling with wrapper function (not entirely
working)
2012-07-05 14:49:59 +01:00
DennisSchiefer 390a14ac77 clarified introduction 2012-07-05 14:46:05 +01:00
DennisSchiefer f2d4f31b8f moved tooltip position a bit down and on top of everything else besides
exclusive notifications
2012-07-05 14:36:01 +01:00
DennisSchiefer ed72366e69 version jump to 0.1.7 2012-07-05 14:32:48 +01:00
DennisSchiefer 6feccd2507 clarified tooltips 2012-07-05 14:31:25 +01:00
DennisSchiefer f27e05564d fixed bug with dragging via markers while an alternative is active 2012-07-05 14:25:42 +01:00
DennisSchiefer d1bc05fcae clarified tooltips,
changed timers to short durations for testing
2012-07-05 14:16:36 +01:00
DennisSchiefer 8323ce78e3 fixed bug with route reversal 2012-07-05 14:08:12 +01:00
DennisSchiefer 517f321ccc Merge branch 'trial/notifications' into develop
Conflicts:
	WebContent/main.html
2012-07-05 14:02:37 +01:00
DennisSchiefer 5e24749826 clarified comments 2012-07-05 14:00:47 +01:00
DennisSchiefer 8f6cd99ff6 changed notification triggers from wrapped functions to simple function
calls
2012-07-05 13:53:07 +01:00
DennisSchiefer efa959d112 added clarifying comment 2012-07-05 13:01:27 +01:00
DennisSchiefer f119b79101 removed comment 2012-07-05 13:00:57 +01:00
DennisSchiefer 8b17e4864e changed check to make sure parameters exist 2012-07-05 09:45:54 +01:00
DennisSchiefer 4ebe4848af Merge branch 'trial/alternatives' into develop
Conflicts:
	WebContent/routing/OSRM.Routing.js
2012-07-05 09:33:00 +01:00
DennisSchiefer ba46d77d1d finalized alternative integration 2012-07-05 09:24:27 +01:00
DennisSchiefer 0c946f1476 added additional notifications,
better argument passing to wrapped trigger functions for notifications,
notification boxes adapt in size to contained text,
notification functions renamed,
2012-07-04 17:27:08 +01:00
DennisSchiefer 22783a53cd wrapper function for localization pulldown menu to work as trigger
function for notifications
2012-07-04 17:25:04 +01:00
DennisSchiefer 770f3b5979 added some notifications 2012-07-04 16:36:10 +01:00
DennisSchiefer a90b2371c2 Merge branch 'trial/geocoder' into develop 2012-07-04 16:15:27 +01:00
DennisSchiefer 052f7060c1 changed look of geocoder results a bit (vertical alignment, debug
messages)
2012-07-04 16:15:04 +01:00
DennisSchiefer 314ff97ca0 nominatim results with type "arial_views" will not be displayed 2012-07-04 15:42:20 +01:00
DennisSchiefer 35bb9efa51 separated normal notifications from important notifications (that lock
the screen)
2012-07-04 15:35:06 +01:00
DennisSchiefer 60436e9928 filter boundaries 2012-07-04 14:07:31 +01:00
DennisSchiefer f575ff2ba5 increased limit on search results 2012-07-04 13:58:06 +01:00
DennisSchiefer 84a960ae1e highlight markers are rendered below normal markers 2012-07-04 13:40:23 +01:00
DennisSchiefer 38ccb9d974 Merge branch 'trial/zooming' into develop 2012-07-04 13:32:36 +01:00
DennisSchiefer 5e3de973d7 recentering/zooming on a route is only done, when the route is first
drawn by clicking on the map and only if the rout doesn't fit into the
current viewport
2012-07-04 13:31:45 +01:00
DennisSchiefer f385ea4e97 modified notification markers, so that a trigger function can be named
that will prevent the notification from happening
2012-07-04 12:36:43 +01:00
DennisSchiefer c38c0b6f03 added notifications 2012-07-04 09:00:11 +01:00
DennisSchiefer 74154ab0a6 alternatives work - sort of 2012-07-04 07:42:49 +01:00
DennisSchiefer c33dbe67d8 printing and alternatives works! 2012-07-03 15:17:29 +01:00
DennisSchiefer 903c4577d1 removed selection restrictions 2012-07-03 14:51:31 +01:00
DennisSchiefer c07f87edca removed geomformat=cmp from jsonp requests as it is now the default 2012-07-03 14:42:23 +01:00
DennisSchiefer 537b9b0623 added stuff to alternatives 2012-07-03 14:39:29 +01:00
DennisSchiefer d88baaf1a4 zoom/pan to route when it doesn't fit on the screen 2012-07-03 13:37:12 +01:00
DennisSchiefer 232409d70b selector elements now use offsetHeight and offsetWidth instead of
clientHeight and clientWidth of invisible selector element
2012-07-03 10:24:10 +01:00
DennisSchiefer c549311349 setting a marker on the map no longer centers on the marker 2012-07-03 10:06:57 +01:00
DennisSchiefer 40c6ac0c28 added letvian translation (thanks to Lauris Bukšis-Haberkorns) 2012-07-03 09:59:16 +01:00
DennisSchiefer 80d2918203 alternatives work with zooming now 2012-06-21 08:26:57 +01:00
shiin 90c48abeaf more alternative stuff 2012-06-20 23:52:43 +02:00
shiin badd48f166 more alternative stuff 2012-06-20 22:08:25 +02:00
DennisSchiefer caa99038c5 no more special characters! 2012-06-18 16:35:10 +01:00
DennisSchiefer ec62156322 additional fix to the slight/sharp left dilema 2012-06-18 16:23:08 +01:00
DennisSchiefer 1423d80556 fixed language error on vs. onto 2012-06-18 08:48:03 +01:00
shiin 59775a9864 more towards alternatives 2012-06-17 18:23:57 +02:00
shiin 7b94a3092f preparation for zooming 2012-06-17 11:04:27 +02:00
shiin 7d82661927 first code for managing alternatives 2012-06-17 09:07:32 +02:00
shiin eeec69dfab added Spanish translation 2012-06-16 13:04:01 +02:00
shiin a8731d91ab fixed bug with "slight left" and "sharp left" instructions being
reversed
2012-06-16 12:44:19 +02:00
DennisSchiefer 3c5c26a8b5 fixed a bug where elements of hidden GUIBoxes could be selected by
tabbing.
2012-06-14 08:08:14 +01:00
DennisSchiefer 2e71ad3060 added fix for touch enabled devices using the layer control 2012-06-14 07:35:26 +01:00
DennisSchiefer 2ad919c970 added geocoder filtering and using Nominatim icons 2012-06-13 10:29:30 +01:00
DennisSchiefer 308b8e5f48 Merge branch 'feature/geocoder' into develop 2012-06-13 07:08:07 +01:00
DennisSchiefer 8677f15d47 zoom button now has same distance to left and right buttons 2012-06-13 07:07:31 +01:00
DennisSchiefer 5923d034c9 added button to zoom on current route 2012-06-12 16:58:16 +01:00
DennisSchiefer 05410d5587 using viewbox, removing zoom-on-route 2012-06-12 15:55:39 +01:00
shiin 1c76c992c1 merged two ideas of raphnik for testing 2012-06-11 14:58:00 +02:00
DennisSchiefer 1973198f3d changed order of loading scripts 2012-05-16 16:27:11 +01:00
DennisSchiefer f2ca2ccaed bumped version to 0.1.6 2012-05-16 12:37:59 +01:00
DennisSchiefer 4cdf683447 Merge branch 'develop'
Conflicts:
	AUTHORS.md
	WebContent/OSRM.config.js
	WebContent/localization/OSRM.Locale.dk.js
	WebContent/localization/OSRM.Locale.pl.js
2012-05-16 12:37:01 +01:00
DennisSchiefer 3bce384f9b changed test server to work server 2012-05-16 12:31:57 +01:00
DennisSchiefer 03bb7f4f40 Merge branch 'trial/viass' into trial/gui 2012-05-16 12:29:44 +01:00
DennisSchiefer c900cd0122 Merge remote-tracking branch 'origin/trial/gui' into trial/gui
Conflicts:
	WebContent/OSRM.config.js
2012-05-16 10:32:21 +01:00
DennisSchiefer 2fbfdc93b1 moved maintenance message to config file 2012-05-16 10:27:25 +01:00
DennisSchiefer cd68e21b95 moved maintenance message to config file 2012-05-16 10:08:10 +01:00
DennisSchiefer 8677218404 transparancy for IE8 2012-05-16 10:07:21 +01:00
DennisSchiefer f6744f9aa1 corrected jsonp call to fetch timestamp 2012-05-16 07:41:36 +01:00
DennisSchiefer df623df3e9 compatibility 2012-05-16 07:34:04 +01:00
shiin 6665207066 added basic maintenance message 2012-05-15 23:02:19 +02:00
shiin 26262541a4 completed language-dependent bing maps 2012-05-15 21:03:58 +02:00
DennisSchiefer ba0064af99 prepared for bing language specific maps 2012-05-15 17:19:09 +01:00
DennisSchiefer 8d40bc7f4f added option to query current layer 2012-05-15 16:24:10 +01:00
DennisSchiefer b85849b6bd fix to timeoutRoute call 2012-05-15 15:10:24 +01:00
DennisSchiefer 543b54e2af fix to polnish translation 2012-05-15 15:10:02 +01:00
DennisSchiefer dfd5ee9134 added via marker numbering 2012-05-15 13:48:24 +01:00
DennisSchiefer 19ae6db308 made timestamp secure against injections 2012-05-15 13:47:36 +01:00
DennisSchiefer 2a634041a7 different colors for history routes 2012-05-15 13:36:21 +01:00
DennisSchiefer 34389f9789 added support for new API regarding via_nodes 2012-05-15 11:39:39 +01:00
DennisSchiefer 2ee7ea87cd prevent bug when first route yields a timeout 2012-05-15 10:42:05 +01:00
DennisSchiefer 6186f3f27e added option for Bing Layers (you still have to provide your own API
key, though!)
2012-05-15 10:33:45 +01:00
DennisSchiefer a53a34a261 integrated attribution fix to Leaflet code 2012-05-15 10:08:40 +01:00
DennisSchiefer e706a9867d data_updated -> data_timestamp 2012-05-14 17:50:17 +01:00
DennisSchiefer 9e5689858e when checking if two routes are equal, only check up to 5 digits 2012-05-14 17:12:02 +01:00
DennisSchiefer 40900f6f56 put Danish after German (de < dk) 2012-05-14 16:31:24 +01:00
DennisSchiefer f266655b9b added data update date 2012-05-14 15:40:23 +01:00
DennisSchiefer 8b0ae1bc5f added Italien translsation (thanks to sabas),
clarified procedure to add commits
2012-05-14 15:39:59 +01:00
DennisSchiefer 979327ec82 refactored code for history routes 2012-05-14 12:18:04 +01:00
DennisSchiefer 0976358fdf added comment 2012-05-14 07:12:29 +01:00
DennisSchiefer 9502689ff8 correction for IE css 2012-05-14 07:06:29 +01:00
shiin 36f5b36c6b more work on history routes 2012-05-13 20:28:24 +02:00
shiin 101fc5d02f removed third parameter from OSRM.bind as it is no longer used 2012-05-13 12:59:19 +02:00
shiin e9736173b0 added clarifying comment to JSONP call 2012-05-13 12:51:49 +02:00
shiin 1ec7c6ab50 did some renaming 2012-05-12 11:33:05 +02:00
shiin f90d1db802 made html + css look better 2012-05-12 08:22:21 +02:00
DennisSchiefer 14ca66459a history routes work now (i hope) 2012-05-11 16:25:06 +01:00
DennisSchiefer e7b3590352 commented out route history 2012-05-11 15:08:04 +01:00
DennisSchiefer c0e86c47c2 changed many names for jsonp routing functions 2012-05-11 12:30:00 +01:00
DennisSchiefer 4a8c2f323c removed comments 2012-05-11 08:23:39 +01:00
DennisSchiefer d4e6ad8a05 added funtionality to the show previous routes button 2012-05-10 15:28:18 +01:00
DennisSchiefer f95e515f20 fixed bug with IE and select elements,
made config box nicer
2012-05-10 14:44:20 +01:00
DennisSchiefer 85ea79701c work on history routes 2012-05-10 14:43:20 +01:00
DennisSchiefer 357ec5acfc danish: da -> dk 2012-05-10 12:53:51 +01:00
DennisSchiefer 47b2268504 test 2012-05-10 12:52:55 +01:00
DennisSchiefer 224c55dec1 fixed bug that did not always remove drag marker on reset 2012-05-10 12:26:56 +01:00
DennisSchiefer 1727187b5e Danish da -> dk 2012-05-10 11:01:50 +01:00
shiin 4d28f02273 route history test 2 2012-05-09 22:34:27 +02:00
shiin a329b1259e finished new gui for language toggle 2012-05-09 22:22:51 +02:00
DennisSchiefer e39479b908 changes localization to new selector elements,
completed units selector,
modified localization selector
2012-05-09 17:27:11 +01:00
DennisSchiefer 2b4935c29c added code to create selector elements with our look&feel 2012-05-09 17:23:11 +01:00
DennisSchiefer 3e15c0a164 tests with showing routing history 2012-05-09 16:22:18 +01:00
DennisSchiefer 7830f82b62 added language support for new elements 2012-05-09 15:21:11 +01:00
shiin 84677ddddf moving UI to new boxes 2012-05-08 22:37:27 +02:00
shiin c8912ad6ee fixed printing bug in IE8 2012-05-08 21:40:55 +02:00
shiin 2d956983a5 finished new box design 2012-05-08 20:52:41 +02:00
DennisSchiefer 884f79a620 new handling of gui boxes (work in progress) 2012-05-08 16:58:08 +01:00
DennisSchiefer 39f33b670d added functions for binding functions to a context and for concating
them
2012-05-08 15:58:54 +01:00
DennisSchiefer a975dba975 first steps to make printing work with IE8 2012-05-08 15:57:25 +01:00
DennisSchiefer 50aea3310a fixed bug that caused wrong destinations when clicking on a routing
instruction after zooming
2012-05-08 13:32:44 +01:00
DennisSchiefer 6c1c830c0d commented out stuff 2012-05-08 10:23:22 +01:00
DennisSchiefer 772ad0d618 added polnish and danish translation, minor version bump 2012-05-07 07:09:56 +01:00
shiin 826cbc9a24 added parameter to set meters/miles,
changed toHumanDistance functions so that conditions don't need to be
checked all the time
2012-05-06 19:10:43 +02:00
shiin 7451cc3150 added Danish translation 2012-05-06 18:45:13 +02:00
shiin 0e9dcc30b7 added miles/feet display (without gui option at the moment) 2012-05-06 18:37:23 +02:00
shiin 222e4e8916 testing route history 2012-05-06 18:36:58 +02:00
DennisSchiefer a3cdba5044 moved localization and printing paths to (internal) variables, so it's
easier to place everything in a different directory
2012-05-04 13:05:30 +01:00
DennisSchiefer 57040e6924 minor fixes in printing for IE8 2012-05-04 08:46:14 +01:00
DennisSchiefer b9a817ce26 bug with redrawing print route 2012-05-03 16:26:11 +01:00
DennisSchiefer 4130144687 removed Leaflet relative path 2012-05-03 15:25:58 +01:00
DennisSchiefer ec5934364a images moved from css style to main.js 2012-05-03 14:18:11 +01:00
DennisSchiefer 23d1ea2a32 polnish tranlation added 2012-05-03 09:06:34 +01:00
shiin 28e78e6ea6 Übersetzung 2012-04-28 08:54:53 +02:00
shiin 90925bd91d made printing window more robust (on refresh, stand-alone opening,
closing browser window...)
2012-04-28 08:33:55 +02:00
shiin 42f38a42db reconverted all routing arrows 2012-04-28 08:32:52 +02:00
shiin ab8c700a94 removed localization directory from config file 2012-04-27 21:09:29 +02:00
shiin 10a96e3aba bugfix 2012-04-27 20:52:53 +02:00
DennisSchiefer 99f0abef0c changed some mouse cursors 2012-04-27 17:29:49 +01:00
DennisSchiefer e7bb320924 bugfix for displaying correct map tile layer when printing 2012-04-27 16:39:06 +01:00
DennisSchiefer 96e5c4b518 version bump 2012-04-27 16:10:03 +01:00
DennisSchiefer a3cfd49f97 shortener reply parameter name flexible,
check if reply is correct,
beautified continue marker
2012-04-27 12:13:27 +01:00
DennisSchiefer fbe722465d individual ids/classes for geocoder search results 2012-04-27 08:55:11 +01:00
DennisSchiefer 448e6cfdc7 gui handling now uses a main class in which all other gui classes plug
in
2012-04-27 08:40:18 +01:00
DennisSchiefer 8e79b29925 changed result-link to route-link 2012-04-27 07:02:37 +01:00
DennisSchiefer bd61494cf4 added authors 2012-04-27 07:01:33 +01:00
DennisSchiefer d33a75812d changed result-link to route-link 2012-04-27 07:01:19 +01:00
DennisSchiefer 9f5f6019bf changed language in html to English 2012-04-26 15:32:48 +01:00
DennisSchiefer aef70b832c josm request will also use only 6 digits precision 2012-04-26 13:45:54 +01:00
DennisSchiefer 611d265a27 corrected display of geocoder results 2012-04-26 13:45:23 +01:00
DennisSchiefer 635b13b61c all route/geocoder requests will only send 6 digits after the decimal
point.
2012-04-26 13:15:41 +01:00
DennisSchiefer a8a4f56292 printing support finalized (yeah!) 2012-04-26 12:49:30 +01:00
DennisSchiefer a0ceee732e added relative root url for Leaflet 2012-04-26 12:48:01 +01:00
DennisSchiefer 560ce74d06 printing window will now be loaded in IE and Chrome 2012-04-26 07:34:51 +01:00
DennisSchiefer d7ffb0d492 trying to get printing to act correctly with Chrome/IE 2012-04-25 16:36:53 +01:00
DennisSchiefer 369edbe9a7 opening josm will only load the current view if you are close enough,
opening josm will no longer trigger a constant loading symbol in
browsers
2012-04-25 15:01:20 +01:00
DennisSchiefer 94ca30c690 printing icon can now deactivates when there is no route 2012-04-25 12:17:36 +01:00
DennisSchiefer ab1e5255eb Merge branch 'trial/folders' into develop 2012-04-25 07:12:02 +01:00
shiin 0068d4062d changed header area for normal routes 2012-04-24 23:23:27 +02:00
shiin 04298b73f3 added image for "head on",
removed unneeded images
2012-04-24 23:06:19 +02:00
DennisSchiefer 7657f0de22 finished printing support (?) 2012-04-24 22:12:24 +02:00
DennisSchiefer 7cdeeb0723 continued work on printing header 2012-04-24 15:28:09 +01:00
DennisSchiefer c0b71cb62a restored large images 2012-04-24 15:24:42 +01:00
DennisSchiefer 253df58fdb beginning to restructure routing header area 2012-04-24 09:38:20 +01:00
DennisSchiefer cd3005f9fe corrected wrong name when querying layers 2012-04-24 09:35:13 +01:00
DennisSchiefer 94cf796ed2 refinement to French translation 2012-04-24 08:50:27 +01:00
DennisSchiefer 18995379ab added explanation for contributing 2012-04-24 07:42:03 +01:00
DennisSchiefer a5246cc8b8 added french to config 2012-04-24 07:41:44 +01:00
DennisSchiefer 3a7f527c68 french translation added, thanks to Nicolas belett VIGNERON,
Moyg, Jean-Frédéric
2012-04-24 07:25:22 +01:00
DennisSchiefer f404337383 Merge remote-tracking branch 'temp/master' into develop 2012-04-24 07:16:38 +01:00
shiin 7421117278 extended mapview to give information about the current visible tile
layer,
continued work on printing
2012-04-24 00:56:41 +02:00
JeanFred f6173b7a48 Add localisation in French 2012-04-23 22:14:27 +02:00
DennisSchiefer dffd67ef72 continued printing work 2012-04-23 17:30:09 +01:00
DennisSchiefer 3444499cf4 onload event can use a different window 2012-04-23 17:29:53 +01:00
DennisSchiefer 7241438502 corrected error ne instead of sw direction 2012-04-23 17:29:18 +01:00
DennisSchiefer 44c38146c9 enabled printing 2012-04-23 14:48:09 +01:00
DennisSchiefer 2060088c6b finished making jsonp parameter names interchangeable 2012-04-23 09:58:34 +01:00
shiin 38defe9629 some files weren't removed properly... 2012-04-23 00:09:22 +02:00
shiin 087bb12847 more file & folder restructuring 2012-04-23 00:08:02 +02:00
shiin c59a6f9444 reorganized folders 2012-04-22 23:48:43 +02:00
shiin 40c0222ffd better UI for route reversal (source/target are changed when response is
received/timeout)
2012-04-22 21:03:50 +02:00
shiin f763ec2664 work-around for invisible scrollbars in Chrome when usind webkit3d 2012-04-22 20:50:09 +02:00
DennisSchiefer 186f78f01e adapted printing to new geometry routines 2012-04-21 08:14:17 +01:00
DennisSchiefer 1da10942d5 changed jsonp call, so that position of the callback command has
to be given as "%jsonp" in the string
2012-04-21 08:13:42 +01:00
DennisSchiefer 7ad253732a link shortener parameters now changeable in config file 2012-04-21 08:11:57 +01:00
DennisSchiefer 4b1c4068f2 Merge branch 'trial/printing' into develop 2012-04-20 12:11:50 +01:00
DennisSchiefer 57ec4e5465 route geometry is requeried 2012-04-20 11:07:47 +01:00
DennisSchiefer f3290ab64b zooming/switching to show unnamed roads will not rebuild the complete
driving directions,
pending JSONP calls can be cleared
2012-04-20 07:37:26 +02:00
DennisSchiefer eb3c2f560e switched back to using normal images in route description (FF wasn't
actually faster, he just reported wrong numbers)
2012-04-19 21:32:07 +02:00
DennisSchiefer 869b13e9db init via_nodes with empty array 2012-04-19 12:59:31 +01:00
DennisSchiefer 57d9bc5bae route direction icons are now background images (which should be faster
in rendering)
2012-04-19 11:02:09 +01:00
DennisSchiefer 917ef160c5 delete route when reversing it 2012-04-19 11:01:18 +01:00
DennisSchiefer ae513dce5c corrected error with marking unnamed streets, introduced by speeding up
route geometry computation
2012-04-19 11:00:57 +01:00
DennisSchiefer 93b5ce2968 switched to small driving direction images 2012-04-19 09:59:36 +01:00
DennisSchiefer ba08d0b36c added road to first driving direction,
allow geographic direction in all driving directions
2012-04-19 09:57:15 +01:00
DennisSchiefer 2e60e92b31 added waiting message to route reversal,
moved reversal logic to OSRM.Markers
2012-04-19 09:48:32 +01:00
DennisSchiefer 5a9a55544b improved speed of decoding route geometry 2012-04-18 16:56:56 +01:00
DennisSchiefer ee7c79641a fixed bug in route reversal (source/target marker would switch colors
when dragged)
2012-04-18 16:55:56 +01:00
DennisSchiefer 6e57c31ec2 added localization to route link 2012-04-18 16:29:44 +01:00
DennisSchiefer 3d9d4f3764 geolocation will no longer interfer with initial position/route passed
to the website,
corrected centering offset of routes
2012-04-18 08:51:31 +01:00
DennisSchiefer 596e7fc60a added cross-browser support for onload event,
made IE8 work again
2012-04-18 07:46:04 +01:00
DennisSchiefer 8845c070a2 moved favicon handling to webserver 2012-04-18 06:56:17 +01:00
DennisSchiefer eaf5dd328f added finnish for overview map 2012-04-17 22:37:15 +02:00
DennisSchiefer 20a0a3b170 Merge remote-tracking branch 'origin/develop' into develop 2012-04-17 22:35:03 +02:00
DennisSchiefer 8d5d1a9400 Merge branch 'trial/printing' into develop 2012-04-17 22:34:18 +02:00
DennisSchiefer 572a306d6d Merge commit 'f2efcfc588f75c391946b1cf8d5600fcf849d3c9' into develop 2012-04-17 22:33:26 +02:00
DennisSchiefer 63a9e4c6c2 remove newline 2012-04-17 22:32:56 +02:00
DennisSchiefer c84d4b323e Merge commit '9bd4b772789b11ca085e7e7f052b410903cf2eb0' into develop 2012-04-17 22:30:28 +02:00
DennisSchiefer 46f717566d added finnish localization 2012-04-17 09:06:15 +01:00
DennisSchiefer 0199673d14 Merge remote-tracking branch 'temp/master' into develop 2012-04-17 09:03:16 +01:00
Teemu Koskinen 607d5408d3 Add Finnish translations 2012-04-16 21:01:40 +03:00
DennisSchiefer 33035fccc0 pushed version 2012-04-16 19:43:57 +02:00
DennisSchiefer c14e461370 added onload_zoomlevel 2012-04-16 19:39:47 +02:00
DennisSchiefer 6f4e9a1d11 added explanation to driving instruction localization 2012-04-16 18:57:21 +02:00
DennisSchiefer 3610e21854 bugfix for zoomlevel in route links 2012-04-16 18:51:22 +02:00
DennisSchiefer f6a3815e91 continued work on printing support 2012-04-16 16:04:36 +01:00
DennisSchiefer f2efcfc588 increased padding when centering on a route 2012-04-16 16:03:59 +01:00
DennisSchiefer 2bf573dbe1 bug in position of " in string 2012-04-16 12:28:51 +01:00
DennisSchiefer 9bd4b77278 use relative image locations 2012-04-16 12:28:16 +01:00
DennisSchiefer fb995ad0b0 small UI move 2012-04-16 10:26:10 +01:00
DennisSchiefer 3a85661e45 fixed bugs with IE 2012-04-16 10:23:31 +01:00
DennisSchiefer 0ba881c390 localization for printing 2012-04-15 23:12:17 +02:00
DennisSchiefer c7782b2776 more work on printing 2012-04-15 23:01:05 +02:00
DennisSchiefer 23ca80030e disabled printing for this release 2012-04-15 19:35:50 +02:00
DennisSchiefer f08c389faa moved version to 0.1.4 2012-04-15 19:35:26 +02:00
DennisSchiefer 47369a0036 continued work on printing support 2012-04-15 19:34:18 +02:00
DennisSchiefer 253b591a87 fixed error with translation of east to German 2012-04-15 19:33:23 +02:00
DennisSchiefer 5c4488d350 removed fixed with from input boxes 2012-04-15 19:32:41 +02:00
DennisSchiefer 25310ff1bd corrected error in via computation when no road was visible 2012-04-15 19:31:49 +02:00
DennisSchiefer c2d52080d3 use geocode even if no route is found 2012-04-14 18:49:28 +02:00
DennisSchiefer bf681855ed moved list of supported languages and tileservers to config file 2012-04-14 18:26:32 +02:00
DennisSchiefer 899d216b9b made it easier to remove localization and on-demand loading of new
language packs,
added parameter to say whether to use on-demand reloading,
added parameter for the directory that contains the localization files,
corrected a small bug when the string for the HEAD_ON instruction was
not available,
2012-04-14 18:03:33 +02:00
DennisSchiefer 73aeab3a57 reworked loading of images and icons (-> easier to add new ones),
adapted routing description to use new description ids,
fixed bug with localization dropdown and FF3,
added localization for "(found X results)"
2012-04-13 17:47:53 +01:00
DennisSchiefer 61073ebc9d added newline to readme 2012-04-12 22:52:18 +02:00
DennisSchiefer 393334cabd corrected error in route description,
made dropdown button more beautiful
2012-04-12 22:44:30 +02:00
DennisSchiefer 01e4afe2f0 changed legal string in html file 2012-04-11 23:07:00 +02:00
DennisSchiefer 9b599c90f8 Merge branch 'trial/printing' into develop
Conflicts:
	WebContent/OSRM.debug.js
2012-04-11 23:03:24 +02:00
DennisSchiefer 252c234221 made parsing of get parameters more robust 2012-04-11 22:59:41 +02:00
DennisSchiefer 888a5d04c8 removal of dragger marker more consistent,
changed printing initialization to be more easily removable from GUI,
localization bug fixes,
added option to give language as get parameter (hl=),
2012-04-11 22:00:19 +02:00
DennisSchiefer b1631eff77 more localization,
fixed bugs with FF3
2012-04-11 17:31:02 +01:00
DennisSchiefer ffd5e2de99 all images are now loaded in main.js 2012-04-10 23:50:04 +02:00
DennisSchiefer ea207cef6e improved language support: geocoding uses language settings, geocoding
results & locations are also translated if possible
2012-04-10 21:47:30 +02:00
DennisSchiefer 893c09f6fc Merge remote-tracking branch 'origin/trial/printing' into trial/printing
Conflicts:
	WebContent/OSRM.GUI.js
2012-04-09 22:35:47 +02:00
shiin 213bb71b35 changed behaviour of geocoder (return always triggers geocoder, moving a
single marker clears search results)
2012-04-09 11:59:32 +02:00
shiin 0fd8d4d8cf all visible lat/lng coordinates are truncated after 6 digits (this
includes inputboxes, osmbugs link, route link, gpx link),
moved all events from html to javascript
2012-04-08 19:50:30 +02:00
shiin 13f0a3fb6b redid html and css,
switched to sans-serif font
2012-04-08 12:02:36 +02:00
shiin 3141d3ba48 prepared localization / route description module to use description ids
instead of description strings
2012-04-06 12:27:23 +02:00
DennisSchiefer 4ff4fcf516 corrected bug in reverse geocoder timeout handler 2012-04-05 09:08:41 +02:00
DennisSchiefer f273f0cfc5 drag marker can no longer be removed by clicking on it 2012-04-05 09:04:48 +02:00
DennisSchiefer dc192d47a8 input boxes are no longer deleted on language change 2012-04-05 01:12:15 +02:00
DennisSchiefer 0f032f7635 bugfix, so that markers will use correct mousepointer again 2012-04-04 15:40:16 +02:00
DennisSchiefer 060c7e499a added bugtracker URL to readme 2012-04-04 15:11:38 +02:00
DennisSchiefer 28a241c371 more testing on printing 2012-04-04 13:08:25 +02:00
DennisSchiefer bab2887f8f Merge branch 'trial/dragging' into develop
Conflicts:
	WebContent/OSRM.JSONP.js
	WebContent/OSRM.debug.js
	WebContent/main.html
2012-04-03 21:30:35 +02:00
DennisSchiefer abba49a44e - added GUI support for language switching
- first tests for support of printing
2012-04-03 21:13:44 +02:00
DennisSchiefer 4638e7c24d corrected error and bumped version to 0.1.3 2012-04-02 20:57:39 +02:00
DennisSchiefer fe420e5bfc added buttons to delete source and target 2012-04-02 08:54:25 +02:00
DennisSchiefer 93ae928236 added icons that can change their image,
added image change while dragging markers,
increased (invisible) size of drag marker,
fixed issues with drag marker and highlight marker overlapping
2012-04-02 08:29:03 +02:00
DennisSchiefer 3b485f1426 finished dragging of routes,
moved corrected bugs in Leaflet to their own file
(drag after dragend, distance to path),
open osmbugs in new window
2012-04-01 19:13:54 +02:00
DennisSchiefer 5165e01a5c added draggable routes,
changed findViaPosition to only return the index and not set the node,
IMPORTANT: changed leaflet-src.js for a bugfix!,
2012-03-30 16:30:16 +01:00
DennisSchiefer 7b4e923ec4 added option (commented out) to use input box for route links to get
a marked url when clicking in it -> test what is better
2012-03-30 10:35:14 +01:00
DennisSchiefer 007dd19cec added buttons to switch to JOSM and OSM Bugs,
added getCenter function that respects UI visibility
2012-03-30 10:10:51 +01:00
DennisSchiefer fd3cf02af4 complete restructure of OSRM.Routing 2012-03-29 16:55:12 +01:00
DennisSchiefer 2bb51717b9 extracted OSRM.Map and OSRM.MapView classes,
moved centering that respects UI visibility to OSRM.MapView
2012-03-29 14:34:55 +01:00
DennisSchiefer 4fe6346146 reordered styles in main.html,
readded default values to GUI,
made TODO marker to check whether GUI is initilaized
2012-03-28 15:02:09 +01:00
DennisSchiefer c5bd2b0b1d renamed routing.js,
encapsulated local helper functions in OSRM.base
2012-03-28 14:30:26 +01:00
DennisSchiefer 71426cf760 changed OSRM debug to work with IE6,
deactivated JSONP timing routines
2012-03-28 14:06:18 +01:00
DennisSchiefer 0ab287e707 modified JSONP statistics,
rearranged OSRM debug so that it works in IE
2012-03-28 13:59:39 +01:00
DennisSchiefer 49cc0bfb09 added functions to test JSONP timings 2012-03-28 13:01:26 +01:00
DennisSchiefer e132ac5c53 moved routing functions to OSRM namespace,
added functions to measure JSONP timings
2012-03-28 12:57:42 +01:00
DennisSchiefer 1a9776cff9 moved utils into OSRM namespace 2012-03-28 12:17:22 +01:00
DennisSchiefer 342a0d22bd - removed bug in centering routes when UI was hidden
- moved all browser dependencies to OSRM.Browser
- refactored via code to use Leaflet functions
- added function to extract route layerPoints
2012-03-28 10:51:54 +01:00
DennisSchiefer 251a43980a switched to Markdown readme 2012-03-26 16:47:40 +01:00
DennisSchiefer 41ba8b5e3e next try 2012-03-26 14:28:38 +01:00
DennisSchiefer 30df2aae10 Do inline links now work with Github asciidoc renderer? 2012-03-26 14:27:18 +01:00
DennisSchiefer a6f00b1856 yet another version 2012-03-26 14:15:44 +01:00
DennisSchiefer af26c47052 GitHUB didn't like my asciidoc... 2012-03-26 14:01:53 +01:00
DennisSchiefer 0a774aeef2 Changed name of README 2012-03-26 13:58:32 +01:00
DennisSchiefer a89aa68686 added README 2012-03-26 13:53:39 +01:00
DennisSchiefer 4b93107415 made logo a bit smaller so that it is centered,
removing source or target now clears route description,
changed GUI handling to no longer be dependent on the actual width of
the sidebar
2012-03-23 18:13:07 +01:00
DennisSchiefer e0602934b2 Refactored Geocoder -> now resides in OSRM namespace 2012-03-23 09:55:55 +01:00
DennisSchiefer fdace26222 changed getPosition().lat / .lng to getLat(), getLng() 2012-03-22 18:31:35 +01:00
DennisSchiefer bef41ed667 geocoder error messages now state the input string,
website is XHTML1.0 strict compliant,
centering now respects if the sidebar is shown,
corrected spelling mistakes
2012-03-22 17:35:09 +01:00
DennisSchiefer 4e2e95cc27 version and date is now taken from OSRM.base,
when source/target markers are deleted the inputbox is emptied
2012-03-19 17:09:03 +01:00
DennisSchiefer f4c6ec90ce fix to route link generator and parser 2012-03-19 10:28:32 +01:00
DennisSchiefer eed22b343a more geocoder refactoring 2012-03-18 22:17:59 +01:00
DennisSchiefer 08ce748a37 removed dirty flags 2012-03-18 22:00:29 +01:00
DennisSchiefer 69790eb8c7 refactored geocoder code (still need to check dirty flags) 2012-03-18 21:44:14 +01:00
DennisSchiefer 97b9c65c97 refactored reverse geocoder 2012-03-18 20:03:15 +01:00
DennisSchiefer 92dbadebae increased zoom level for route description (new config entry),
removed some deprecated comments
2012-03-18 18:17:04 +01:00
DennisSchiefer fe6d854e11 improved handling of dragging,
link to route gui improved,
JSONP can now take parameters
2012-03-18 17:42:05 +01:00
DennisSchiefer 4615b01fdf moved inputbox logic to javascript file,
corrected error with second ENTER not being registered
2012-03-18 15:04:17 +01:00
DennisSchiefer 276b023b05 changed checking if eventhandler storage exists 2012-03-18 12:29:02 +01:00
DennisSchiefer 350cacb2f3 added try-finally guards to JSONP calls 2012-03-18 11:38:21 +01:00
DennisSchiefer 25ec6105c5 reverse geocoding now always shows two information if possible 2012-03-17 22:26:57 +01:00
DennisSchiefer 3e4249ad41 used abbreviations for sub-namespaces GLOBALS, CONSTANTS 2012-03-17 20:49:19 +01:00
DennisSchiefer 13126ac0c1 moved all variables/objects to OSRM namespace 2012-03-17 20:43:52 +01:00
DennisSchiefer d51aee4fbe bugfix to route link storing map view location 2012-03-17 17:07:34 +01:00
DennisSchiefer f9877fd8ba refactoring: used hasSource, hasTarget routines throughout the code 2012-03-17 17:04:45 +01:00
DennisSchiefer a39a35df73 moved leaflet.ie.css to new position 2012-03-17 15:48:24 +01:00
DennisSchiefer 2670dd68f3 added event handler base class 2012-03-17 15:28:27 +01:00
DennisSchiefer 9adb590ce7 added OSRM.CONSTANTS, OSRM.GLOBALS for better structuring,
improved comments in OSRM.base.js and OSRM.config.js
2012-03-17 14:45:04 +01:00
DennisSchiefer 9567a7e38c added support for saving route zoom level and position in route links 2012-03-17 14:17:08 +01:00
DennisSchiefer d86eaa00a0 compressed target.png 2012-03-16 18:27:52 +01:00
DennisSchiefer 54c0d50b68 reseting now also resets OSRM.JSONP 2012-03-16 17:52:10 +01:00
DennisSchiefer 204189c326 - version bump to v0.1.1
- restructured buttons (route is gone, search is show)
- added prefetching gui hide/show buttons
- increased timeout to 5000ms
- click highlight marker to hide it
- boundary box on Europe when querying geocoder
- added "reached your destination" display in route instructions
- improved visual for route summary
- when loading a stored route, source and target are named and the route
is zoomed correctly
- improved display results of reverse geocoder (ues village/country
tags)
- more consistent behaviour when displaying reverse geocoder results
or geocoordinates
- reverse geocoder now works at dragend
- more consistent behaviour when leaving an input box
- reversing a route when only one marker is set empties the result box
2012-03-16 15:06:43 +01:00
DennisSchiefer acdfa546a8 added more precise distance values (at least three digits of precision) 2012-03-16 10:41:54 +01:00
DennisSchiefer 6a9216d6e4 added functions to check whether source or target exists,
readded routing button
2012-03-16 09:42:14 +01:00
DennisSchiefer 9c2a1dc37f implemented several security measures when parsing GET input to the site 2012-03-16 09:07:03 +01:00
DennisSchiefer 26c9d357f0 made reverse geocoding more intuitive,
changed search and route buttons to centering buttons
2012-03-16 07:22:47 +01:00
DennisSchiefer 879d73c629 testing to remove route button -> search will be automatical on lost
focus
2012-03-15 17:45:22 +01:00
DennisSchiefer 441146eeae changed look of route description header area 2012-03-15 17:42:17 +01:00
DennisSchiefer d453cadc8c added call option to set destination when calling the site 2012-03-15 14:22:00 +01:00
DennisSchiefer 74188206e8 website url is now retrieved directly from browser,
removed unneeded localization strings
2012-03-15 14:01:34 +01:00
DennisSchiefer 700206099b made route reset more robust by clearing *really* everything,
improved route description (added distances to the right, bold street
names, orientation in first instruction and non-breaking spaces for
units),
route link now displays the shortened link name,
content of input boxes is only overwritten if the respective node is
set or dragged,
experimental support for reverse geocoding (when setting a new node by
text box or clicking on map)
2012-03-15 13:29:28 +01:00
DennisSchiefer aa952df541 added favicon,
removed commata that IE was complaining about
2012-03-15 09:05:00 +01:00
DennisSchiefer b8944da9dc prevent browser context menu on map 2012-03-14 18:07:15 +01:00
DennisSchiefer 22dda2b285 added new gui buttons for opening/closing,
route button now works,
more precise error message when geocoder does not find a result,
added maximum input length for text boxes
2012-03-14 17:42:14 +01:00
DennisSchiefer 0ee469c4e0 Merge branch 'develop' of
https://DennisSchiefer@bitbucket.org/DennisSchiefer/project-osrm-web.git
into develop

Conflicts:
	WebContent/routing.js
2012-03-14 16:50:14 +01:00
DennisSchiefer a7eef27e99 added legal headers,
beautified comments,
moved language settings to config,
moved timeout settings to config,
corrected bug with route link and via nodes,
removed old files,
corrected spelling error for roundabout
2012-03-14 16:45:15 +01:00
DennisSchiefer 4b40f1253f added legal headers,
beautified comments,
moved language settings to config,
moved timeout settings to config,
corrected bug with route link and via nodes
removed old files
2012-03-14 16:30:11 +01:00
DennisSchiefer 5ebe8080f9 small bug class/id mixed up 2012-03-14 11:24:40 +01:00
DennisSchiefer d92b28d2c3 restructured for release 2012-03-14 10:39:37 +01:00
DennisSchiefer ec27881f39 test fencing 2012-03-13 22:39:28 +01:00
DennisSchiefer c5a8ec7c31 added better lat/lng display when dragging,
added experimental faster route redraw (commented out),
changed default website url and routing url,
removed drag after dragend event workaround
2012-03-13 22:25:40 +01:00
DennisSchiefer afbd3347da added clear debug log button,
removed showing of links in gpx, route requests,
checked html with validator
2012-03-13 20:51:44 +01:00
DennisSchiefer 41bcafc3a1 added lat/lng processing 2012-03-13 17:57:48 +01:00
DennisSchiefer 27d24885a9 debug window stays at botoom when adding data 2012-03-13 17:36:40 +01:00
DennisSchiefer 805402b230 starting to reverse geocoding 2012-03-13 17:32:18 +01:00
DennisSchiefer 4918549bac fixed bug when selecting city options in geocoder,
added clicking on map to create markers,
reset also clears input boxes now
2012-03-13 15:26:53 +01:00
DennisSchiefer 784f417857 changed geocoder to official OSM geocoder,
switched default map style to osm.org
2012-03-13 14:31:23 +01:00
DennisSchiefer 0bc3e098ac added GUI support for IE9 and IE10,
changed GUI legal text,
changed via-node deletion to click only,
moved default entries for input boxes to config file,
made input boxes selectable again
2012-03-13 14:15:07 +01:00
DennisSchiefer dfd3a5d554 changed round-about symbol, corrected bug with ENTER not working on
location input
2012-03-13 10:26:31 +01:00
DennisSchiefer 9dcc472c60 Merge branch 'feature/prefetching' into develop 2012-03-12 13:33:14 +01:00
DennisSchiefer c972e2cf41 Merge branch 'gui/buttons' into develop 2012-03-12 13:26:38 +01:00
DennisSchiefer de9ab83cea ignore eclipse files 2012-03-12 13:16:32 +01:00
schiefer 174e388e2d debug window added,
when including OSRM.debug, a debug window is shown
2012-03-12 11:33:39 +01:00
DennisSchiefer ee41fb45b7 added more turn instructions, changed clickability of gui 2012-03-10 17:08:25 +01:00
schiefer 93892b9806 changed buttons look 2012-03-09 17:33:06 +01:00
schiefer 749d83a69f - store prefetched images permanently
(otherwise they are not prefetched before the function terminated)
- store each type of marker icon once
2012-03-09 15:26:32 +01:00
schiefer 8b109904c8 initial import 2012-03-09 09:24:51 +01:00
310 changed files with 18093 additions and 19832 deletions
+2 -72
View File
@@ -1,72 +1,2 @@
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store?
ehthumbs.db
Icon?
Thumbs.db
# SCons related files #
#######################
SconsBuilder*
.scon*
.build
# Eclipse related files #
#########################
.setting*
.scb
.cproject
.project
# stxxl related files #
#######################
.stxxl
stxxl.log
stxxl.errlog
# compiled protobuffers #
#########################
DataStructures/pbf-proto/*.pb.h
DataStructures/pbf-proto/*.pb.cc
# External Libs #
#################
lib/
# Visual Studio Temp + build Files #
####################################
vcprojects/*.user
vcprojects/*.ncb
vcprojects/*.suo
vcprojects/Debug/
vcprojects/Release/
bin/
bin-debug/
/.settings
/.project
-10
View File
@@ -1,10 +0,0 @@
The following people contributed code to the Open Source Routing Machine:
Christian Vetter
Dennis Luxen
Ruslan Krenzler
Frederik Ramm
Bharath Vissapragada
Pascal Neis
Sasa Ivetic
Emil Tin
+24
View File
@@ -0,0 +1,24 @@
The following people contributed to the Open Source Routing Machine web frontend:
Dennis Schieferdecker
Dennis Luxen
Pascal Neis
Teemu Koskinen
Nicolas Belett Vigneron
Moyg
Jean-Frederic
Zbigniew Czernik
Jonas Häggqvist
Sabas
Paul Spencer
Raphael Pinson
Juan Luis Rodriguez Ponce
Lauris Bukšis-Haberkorns
Barboska
miszka999
Konstantin Delchev
Fumito Mizuno
Necdet Varoglu (OSM-Comenius Project)
Madalina Ionescu (OSM-Comenius Project)
Luis Costa (OSM-Comenius Project)
Tobias Johansson
-126
View File
@@ -1,126 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#include <cfloat>
#include <stack>
/*This class object computes the bitvector of indicating generalized input points
* according to the (Ramer-)Douglas-Peucker algorithm.
*
* Input is vector of pairs. Each pair consists of the point information and a bit
* indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
//These thresholds are more or less heuristically chosen.
static double DouglasPeuckerThresholds[19] = { 10240000., 512., 2560000., 1280000., 640000., 320000., 160000., 80000., 40000., 20000., 10000., 5000., 2400., 1200., 200, 16, 6, 3., 1. };
template<class PointT>
class DouglasPeucker {
private:
typedef std::pair<std::size_t, std::size_t> PairOfPoints;
//Stack to simulate the recursion
std::stack<PairOfPoints > recursionStack;
double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target) {
double r;
const double x = (double)inputPoint.lat;
const double y = (double)inputPoint.lon;
const double a = (double)source.lat;
const double b = (double)source.lon;
const double c = (double)target.lat;
const double d = (double)target.lon;
double p,q,mX,nY;
if(c != a) {
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1 + m*m);
q = b + m*(p - a);
} else {
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
r = mX;
if(r<=0){
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(r >= 1){
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
return (p-x)*(p-x) + (q-y)*(q-y);
}
public:
void Run(std::vector<PointT> & inputVector, const unsigned zoomLevel) {
{
assert(zoomLevel < 19);
assert(1 < inputVector.size());
std::size_t leftBorderOfRange = 0;
std::size_t rightBorderOfRange = 1;
//Sweep linerarily over array and identify those ranges that need to be checked
do {
assert(inputVector[leftBorderOfRange].necessary);
assert(inputVector[inputVector.size()-1].necessary);
if(inputVector[rightBorderOfRange].necessary) {
recursionStack.push(std::make_pair(leftBorderOfRange, rightBorderOfRange));
leftBorderOfRange = rightBorderOfRange;
}
++rightBorderOfRange;
} while( rightBorderOfRange < inputVector.size());
}
while(!recursionStack.empty()) {
//pop next element
const PairOfPoints pair = recursionStack.top();
recursionStack.pop();
assert(inputVector[pair.first].necessary);
assert(inputVector[pair.second].necessary);
assert(pair.second < inputVector.size());
assert(pair.first < pair.second);
double maxDistance = -DBL_MAX;
std::size_t indexOfFarthestElement = pair.second;
//find index idx of element with maxDistance
for(std::size_t i = pair.first+1; i < pair.second; ++i){
double distance = std::fabs(ComputeDistance(inputVector[i].location, inputVector[pair.first].location, inputVector[pair.second].location));
if(distance > DouglasPeuckerThresholds[zoomLevel] && distance > maxDistance) {
indexOfFarthestElement = i;
maxDistance = distance;
}
}
if (maxDistance > DouglasPeuckerThresholds[zoomLevel]) {
// mark idx as necessary
inputVector[indexOfFarthestElement].necessary = true;
if (1 < indexOfFarthestElement - pair.first) {
recursionStack.push(std::make_pair(pair.first, indexOfFarthestElement) );
}
if (1 < pair.second - indexOfFarthestElement)
recursionStack.push(std::make_pair(indexOfFarthestElement, pair.second) );
}
}
}
};
#endif /* DOUGLASPEUCKER_H_ */
-134
View File
@@ -1,134 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
#include <string>
#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/StringUtil.h"
class PolylineCompressor {
private:
inline void encodeVectorSignedNumber(vector<int> & numbers, string & output) {
for(unsigned i = 0; i < numbers.size(); ++i) {
numbers[i] <<= 1;
if (numbers[i] < 0) {
numbers[i] = ~(numbers[i]);
}
}
for(unsigned i = 0; i < numbers.size(); ++i) {
encodeNumber(numbers[i], output);
}
}
inline void encodeNumber(int numberToEncode, string & output) {
while (numberToEncode >= 0x20) {
int nextValue = (0x20 | (numberToEncode & 0x1f)) + 63;
output += (static_cast<char> (nextValue));
if(92 == nextValue)
output += (static_cast<char> (nextValue));
numberToEncode >>= 5;
}
numberToEncode += 63;
output += (static_cast<char> (numberToEncode));
if(92 == numberToEncode)
output += (static_cast<char> (numberToEncode));
}
public:
inline void printEncodedString(const vector<SegmentInformation>& polyline, string &output) {
vector<int> deltaNumbers;
output += "\"";
if(!polyline.empty()) {
_Coordinate lastCoordinate = polyline[0].location;
deltaNumbers.push_back( lastCoordinate.lat );
deltaNumbers.push_back( lastCoordinate.lon );
for(unsigned i = 1; i < polyline.size(); ++i) {
if(!polyline[i].necessary)
continue;
deltaNumbers.push_back(polyline[i].location.lat - lastCoordinate.lat);
deltaNumbers.push_back(polyline[i].location.lon - lastCoordinate.lon);
lastCoordinate = polyline[i].location;
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
inline void printEncodedString(const vector<_Coordinate>& polyline, string &output) {
vector<int> deltaNumbers(2*polyline.size());
output += "\"";
if(!polyline.empty()) {
deltaNumbers[0] = polyline[0].lat;
deltaNumbers[1] = polyline[0].lon;
for(unsigned i = 1; i < polyline.size(); ++i) {
deltaNumbers[(2*i)] = (polyline[i].lat - polyline[i-1].lat);
deltaNumbers[(2*i)+1] = (polyline[i].lon - polyline[i-1].lon);
}
encodeVectorSignedNumber(deltaNumbers, output);
}
output += "\"";
}
inline void printUnencodedString(vector<_Coordinate> & polyline, string & output) {
output += "[";
string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
convertInternalLatLonToString(polyline[i].lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
inline void printUnencodedString(vector<SegmentInformation> & polyline, string & output) {
output += "[";
string tmp;
for(unsigned i = 0; i < polyline.size(); i++) {
if(!polyline[i].necessary)
continue;
convertInternalLatLonToString(polyline[i].location.lat, tmp);
output += "[";
output += tmp;
convertInternalLatLonToString(polyline[i].location.lon, tmp);
output += ", ";
output += tmp;
output += "]";
if( i < polyline.size()-1 ) {
output += ",";
}
}
output += "]";
}
};
#endif /* POLYLINECOMPRESSOR_H_ */
-290
View File
@@ -1,290 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONTRACTIONCLEANUP_H_INCLUDED
#define CONTRACTIONCLEANUP_H_INCLUDED
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "Contractor.h"
#ifdef _OPENMP
#include <omp.h>
#endif
class ContractionCleanup {
private:
struct _CleanupHeapData {
NodeID parent;
_CleanupHeapData( NodeID p ) {
parent = p;
}
};
#ifdef _MANYCORES
typedef BinaryHeap< NodeID, NodeID, int, _HeapData, DenseStorage<NodeID, NodeID> > _Heap;
#else
typedef BinaryHeap< NodeID, NodeID, int, _CleanupHeapData > _Heap;
#endif
struct _ThreadData {
_Heap* _heapForward;
_Heap* _heapBackward;
_ThreadData( NodeID nodes ) {
_heapBackward = new _Heap(nodes);
_heapForward = new _Heap(nodes);
}
~_ThreadData()
{
delete _heapBackward;
delete _heapForward;
}
};
public:
struct Edge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID via;
unsigned nameID1;
unsigned nameID2;
int distance;
bool shortcut;
bool forward;
bool backward;
short turnInstruction;
} data;
//sorts by source and other attributes
static bool CompareBySource( const Edge& left, const Edge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID1 == right.data.nameID1 && data.nameID2 == right.data.nameID2
);
}
};
ContractionCleanup( int numNodes, const std::vector< Edge >& edges ) {
_graph = edges;
_numNodes = numNodes;
}
~ContractionCleanup() {
}
void Run() {
RemoveUselessShortcuts();
}
template< class EdgeT >
void GetData( std::vector< EdgeT >& edges ) {
for ( int edge = 0, endEdges = ( int ) _graph.size(); edge != endEdges; ++edge ) {
if(_graph[edge].data.forward || _graph[edge].data.backward) {
EdgeT newEdge;
newEdge.source = _graph[edge].source;
newEdge.target = _graph[edge].target;
newEdge.data = _graph[edge].data;
edges.push_back( newEdge );
}
}
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( edges.begin(), edges.end() );
#else
sort( edges.begin(), edges.end() );
#endif
}
private:
double _Timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
void BuildOutgoingGraph() {
//sort edges by source
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
#else
sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
#endif
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
cerr << "Not enough RAM on machine" << endl;
return;
}
_firstEdge[0] = 0;
for ( NodeID i = 0, node = 0; i < ( NodeID ) _graph.size(); i++ ) {
while ( _graph[i].source != node )
_firstEdge[++node] = i;
if ( i == ( NodeID ) _graph.size() - 1 )
while ( node < _numNodes )
_firstEdge[++node] = ( int ) _graph.size();
}
}
void RemoveUselessShortcuts() {
int maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( _numNodes ) );
}
cout << "Scanning for useless shortcuts" << endl;
BuildOutgoingGraph();
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
for ( unsigned edge = _firstEdge[_graph[i].source]; edge < _firstEdge[_graph[i].source + 1]; ++edge ) {
if ( edge == (unsigned)i )
continue;
if ( _graph[edge].target != _graph[i].target )
continue;
if ( _graph[edge].data.distance < _graph[i].data.distance )
continue;
_graph[edge].data.forward &= !_graph[i].data.forward;
_graph[edge].data.backward &= !_graph[i].data.backward;
}
if ( !_graph[i].data.forward && !_graph[i].data.backward )
continue;
//only remove shortcuts
if ( !_graph[i].data.shortcut )
continue;
if ( _graph[i].data.forward ) {
int result = _ComputeDistance( _graph[i].source, _graph[i].target, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.forward = false;
}
}
if ( _graph[i].data.backward ) {
int result = _ComputeDistance( _graph[i].target, _graph[i].source, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.backward = false;
}
}
}
cout << "Removing edges" << endl;
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut )
continue;
_graph[useful] = _graph[i];
useful++;
}
cout << "Removed " << _graph.size() - useful << " useless shortcuts" << endl;
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
delete threadData[threadNum];
}
}
void _ComputeStep( _Heap* heapForward, _Heap* heapBackward, bool forwardDirection, NodeID* middle, int* targetDistance ) {
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
*middle = node;
*targetDistance = newDistance;
}
}
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
if ( (forwardDirection ? _graph[edge].data.forward : _graph[edge].data.backward ) ) {
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heapForward->WasInserted( to ) )
heapForward->Insert( to, toDistance, node );
//Found a shorter Path -> Update distance
else if ( toDistance < heapForward->GetKey( to ) ) {
heapForward->DecreaseKey( to, toDistance );
//new parent
heapForward->GetData( to ) = node;
}
}
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data, std::vector< NodeID >* path = NULL ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = (std::numeric_limits< int >::max)();
NodeID middle = (std::numeric_limits<NodeID>::max)();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
_ComputeStep( data->_heapForward, data->_heapBackward, true, &middle, &targetDistance );
}
if ( data->_heapBackward->Size() > 0 ) {
_ComputeStep( data->_heapBackward, data->_heapForward, false, &middle, &targetDistance );
}
}
return targetDistance;
}
NodeID _numNodes;
std::vector< Edge > _graph;
std::vector< unsigned > _firstEdge;
};
#endif // CONTRACTIONCLEANUP_H_INCLUDED
-570
View File
@@ -1,570 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONTRACTOR_H_INCLUDED
#define CONTRACTOR_H_INCLUDED
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#include <boost/shared_ptr.hpp>
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/BinaryHeap.h"
#include <ctime>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <limits>
#ifdef _OPEMP
#include <omp.h>
#endif
class Contractor {
private:
struct _EdgeBasedContractorEdgeData {
unsigned distance;
unsigned originalEdges;
unsigned via;
unsigned nameID;
bool shortcut;
bool forward;
bool backward;
short turnInstruction;
} data;
struct _HeapData {
bool target;
_HeapData() : target(false) {}
_HeapData( bool t ) : target(t) {}
};
typedef DynamicGraph< _EdgeBasedContractorEdgeData > _DynamicGraph;
typedef BinaryHeap< NodeID, NodeID, int, _HeapData> _Heap;
typedef _DynamicGraph::InputEdge _ImportEdge;
struct _ThreadData {
_Heap heap;
std::vector< _ImportEdge > insertedEdges;
std::vector< NodeID > neighbours;
_ThreadData( NodeID nodes ): heap( nodes ) {
}
};
struct _PriorityData {
int depth;
NodeID bias;
_PriorityData() : depth(0), bias(0) { }
};
struct _ContractionInformation {
int edgesDeleted;
int edgesAdded;
int originalEdgesDeleted;
int originalEdgesAdded;
_ContractionInformation() {
edgesAdded = edgesDeleted = originalEdgesAdded = originalEdgesDeleted = 0;
}
};
struct _NodePartitionor {
bool operator()( std::pair< NodeID, bool > nodeData ) {
return !nodeData.second;
}
};
public:
template< class InputEdge >
Contractor( int nodes, std::vector< InputEdge >& inputEdges, unsigned eqf = 2, unsigned oqf = 1, unsigned df = 1) : edgeQuotionFactor(eqf), originalQuotientFactor(oqf), depthFactor(df) {
std::vector< _ImportEdge > edges;
edges.reserve( 2 * inputEdges.size() );
for ( typename std::vector< InputEdge >::const_iterator i = inputEdges.begin(), e = inputEdges.end(); i != e; ++i ) {
_ImportEdge edge;
edge.source = i->source();
edge.target = i->target();
edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 );
#ifndef NDEBUG
if ( edge.data.distance > 24 * 60 * 60 * 10 ) {
std::cout << "Edge Weight too large -> May lead to invalid CH" << std::endl;
continue;
}
#endif
edge.data.shortcut = false;
edge.data.nameID = i->getNameIDOfTurnTarget();
edge.data.via = i->via();
edge.data.turnInstruction = i->turnInstruction();
edge.data.forward = i->isForward();
edge.data.backward = i->isBackward();
edge.data.originalEdges = 1;
edges.push_back( edge );
std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edges.push_back( edge );
}
//remove data from memory
inputEdges.clear();
std::vector< InputEdge >().swap( inputEdges );
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( edges.begin(), edges.end() );
#else
sort( edges.begin(), edges.end() );
#endif
NodeID edge = 0;
for ( NodeID i = 0; i < edges.size(); ) {
const NodeID source = edges[i].source;
const NodeID target = edges[i].target;
const NodeID via = edges[i].data.via;
const short turnType = edges[i].data.turnInstruction;
//remove eigenloops
if ( source == target ) {
i++;
continue;
}
_ImportEdge forwardEdge;
_ImportEdge backwardEdge;
forwardEdge.source = backwardEdge.source = source;
forwardEdge.target = backwardEdge.target = target;
forwardEdge.data.forward = backwardEdge.data.backward = true;
forwardEdge.data.backward = backwardEdge.data.forward = false;
forwardEdge.data.turnInstruction = backwardEdge.data.turnInstruction = turnType;
forwardEdge.data.nameID = backwardEdge.data.nameID = edges[i].data.nameID;
forwardEdge.data.shortcut = backwardEdge.data.shortcut = false;
forwardEdge.data.via = backwardEdge.data.via = via;
forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1;
forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max();
//remove parallel edges
while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) {
if ( edges[i].data.forward )
forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance );
if ( edges[i].data.backward )
backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance );
i++;
}
//merge edges (s,t) and (t,s) into bidirectional edge
if ( forwardEdge.data.distance == backwardEdge.data.distance ) {
if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) {
forwardEdge.data.backward = true;
edges[edge++] = forwardEdge;
}
} else { //insert seperate edges
if ( ((int)forwardEdge.data.distance) != std::numeric_limits< int >::max() ) {
edges[edge++] = forwardEdge;
}
if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) {
edges[edge++] = backwardEdge;
}
}
}
std::cout << "ok" << std::endl << "merged " << edges.size() - edge << " edges out of " << edges.size() << std::endl;
edges.resize( edge );
_graph.reset( new _DynamicGraph( nodes, edges ) );
std::vector< _ImportEdge >().swap( edges );
}
~Contractor() { }
void Run() {
const NodeID numberOfNodes = _graph->GetNumberOfNodes();
Percent p (numberOfNodes);
unsigned maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( numberOfNodes ) );
}
std::cout << "Contractor is using " << maxThreads << " threads" << std::endl;
NodeID levelID = 0;
std::vector< std::pair< NodeID, bool > > remainingNodes( numberOfNodes );
std::vector< double > nodePriority( numberOfNodes );
std::vector< _PriorityData > nodeData( numberOfNodes );
//initialize the variables
#pragma omp parallel for schedule ( guided )
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
remainingNodes[x].first = x;
std::random_shuffle( remainingNodes.begin(), remainingNodes.end() );
for ( int x = 0; x < ( int ) numberOfNodes; ++x )
nodeData[remainingNodes[x].first].bias = x;
std::cout << "initializing elimination PQ ..." << std::flush;
#pragma omp parallel
{
_ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp parallel for schedule ( guided )
for ( int x = 0; x < ( int ) numberOfNodes; ++x ) {
nodePriority[x] = _Evaluate( data, &nodeData[x], x );
}
}
std::cout << "ok" << std::endl << "preprocessing ..." << std::flush;
while ( levelID < numberOfNodes ) {
const int last = ( int ) remainingNodes.size();
#pragma omp parallel
{
//determine independent node set
_ThreadData* const data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided )
for ( int i = 0; i < last; ++i ) {
const NodeID node = remainingNodes[i].first;
remainingNodes[i].second = _IsIndependent( nodePriority, nodeData, data, node );
}
}
_NodePartitionor functor;
const std::vector < std::pair < NodeID, bool > >::const_iterator first = stable_partition( remainingNodes.begin(), remainingNodes.end(), functor );
const int firstIndependent = first - remainingNodes.begin();
//contract independent nodes
#pragma omp parallel
{
_ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first;
_Contract< false > ( data, x );
nodePriority[x] = -1;
}
std::sort( data->insertedEdges.begin(), data->insertedEdges.end() );
}
#pragma omp parallel
{
_ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first;
_DeleteIncomingEdges( data, x );
}
}
//insert new edges
for ( unsigned threadNum = 0; threadNum < maxThreads; ++threadNum ) {
_ThreadData& data = *threadData[threadNum];
for ( int i = 0; i < ( int ) data.insertedEdges.size(); ++i ) {
const _ImportEdge& edge = data.insertedEdges[i];
_graph->InsertEdge( edge.source, edge.target, edge.data );
}
std::vector< _ImportEdge >().swap( data.insertedEdges );
}
//update priorities
#pragma omp parallel
{
_ThreadData* data = threadData[omp_get_thread_num()];
#pragma omp for schedule ( guided ) nowait
for ( int position = firstIndependent ; position < last; ++position ) {
NodeID x = remainingNodes[position].first;
_UpdateNeighbours( &nodePriority, &nodeData, data, x );
}
}
//remove contracted nodes from the pool
levelID += last - firstIndependent;
remainingNodes.resize( firstIndependent );
std::vector< std::pair< NodeID, bool > >( remainingNodes ).swap( remainingNodes );
p.printStatus(levelID);
}
for ( unsigned threadNum = 0; threadNum < maxThreads; threadNum++ ) {
delete threadData[threadNum];
}
}
template< class Edge >
void GetEdges( std::vector< Edge >& edges ) {
NodeID numberOfNodes = _graph->GetNumberOfNodes();
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge < endEdges; edge++ ) {
const NodeID target = _graph->GetTarget( edge );
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
Edge newEdge;
newEdge.source = node;
newEdge.target = target;
newEdge.data.distance = data.distance;
newEdge.data.shortcut = data.shortcut;
newEdge.data.via = data.via;
newEdge.data.nameID1 = data.nameID;
newEdge.data.turnInstruction = data.turnInstruction;
newEdge.data.forward = data.forward;
newEdge.data.backward = data.backward;
edges.push_back( newEdge );
}
}
}
private:
void _Dijkstra( const int maxDistance, const unsigned numTargets, const int maxNodes, _ThreadData* data ){
_Heap& heap = data->heap;
int nodes = 0;
unsigned targetsFound = 0;
while ( heap.Size() > 0 ) {
const NodeID node = heap.DeleteMin();
const int distance = heap.GetKey( node );
if ( nodes++ > maxNodes )
return;
//Destination settled?
if ( distance > maxDistance )
return;
if ( heap.GetData( node ).target ) {
targetsFound++;
if ( targetsFound >= numTargets )
return;
}
//iterate over all edges of node
for ( _DynamicGraph::EdgeIterator edge = _graph->BeginEdges( node ), endEdges = _graph->EndEdges( node ); edge != endEdges; ++edge ) {
const _EdgeBasedContractorEdgeData& data = _graph->GetEdgeData( edge );
if ( !data.forward )
continue;
const NodeID to = _graph->GetTarget( edge );
const int toDistance = distance + data.distance;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heap.WasInserted( to ) )
heap.Insert( to, toDistance, _HeapData() );
//Found a shorter Path -> Update distance
else if ( toDistance < heap.GetKey( to ) ) {
heap.DecreaseKey( to, toDistance );
//heap.GetData( to ).hops = hops + 1;
}
}
}
}
double _Evaluate( _ThreadData* const data, _PriorityData* const nodeData, NodeID node ){
_ContractionInformation stats;
//perform simulated contraction
_Contract< true > ( data, node, &stats );
// Result will contain the priority
if ( stats.edgesDeleted == 0 || stats.originalEdgesDeleted == 0 )
return depthFactor * nodeData->depth;
return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth;
}
template< bool Simulate > bool _Contract( _ThreadData* data, NodeID node, _ContractionInformation* stats = NULL ) {
_Heap& heap = data->heap;
int insertedEdgesSize = data->insertedEdges.size();
std::vector< _ImportEdge >& insertedEdges = data->insertedEdges;
for ( _DynamicGraph::EdgeIterator inEdge = _graph->BeginEdges( node ), endInEdges = _graph->EndEdges( node ); inEdge != endInEdges; ++inEdge ) {
const _EdgeBasedContractorEdgeData& inData = _graph->GetEdgeData( inEdge );
const NodeID source = _graph->GetTarget( inEdge );
if ( Simulate ) {
assert( stats != NULL );
stats->edgesDeleted++;
stats->originalEdgesDeleted += inData.originalEdges;
}
if ( !inData.backward )
continue;
heap.Clear();
heap.Insert( source, 0, _HeapData() );
if ( node != source )
heap.Insert( node, inData.distance, _HeapData() );
int maxDistance = 0;
unsigned numTargets = 0;
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward )
continue;
const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance;
maxDistance = std::max( maxDistance, pathDistance );
if ( !heap.WasInserted( target ) ) {
heap.Insert( target, pathDistance, _HeapData( true ) );
numTargets++;
} else if ( pathDistance < heap.GetKey( target ) ) {
heap.DecreaseKey( target, pathDistance );
}
}
if( Simulate )
_Dijkstra( maxDistance, numTargets, 500, data );
else
_Dijkstra( maxDistance, numTargets, 1000, data );
for ( _DynamicGraph::EdgeIterator outEdge = _graph->BeginEdges( node ), endOutEdges = _graph->EndEdges( node ); outEdge != endOutEdges; ++outEdge ) {
const _EdgeBasedContractorEdgeData& outData = _graph->GetEdgeData( outEdge );
if ( !outData.forward )
continue;
const NodeID target = _graph->GetTarget( outEdge );
const int pathDistance = inData.distance + outData.distance;
const int distance = heap.GetKey( target );
if ( pathDistance <= distance ) {
if ( Simulate ) {
assert( stats != NULL );
stats->edgesAdded+=2;
stats->originalEdgesAdded += 2* ( outData.originalEdges + inData.originalEdges );
} else {
_ImportEdge newEdge;
newEdge.source = source;
newEdge.target = target;
newEdge.data.distance = pathDistance;
newEdge.data.forward = true;
newEdge.data.backward = false;
newEdge.data.via = node;
newEdge.data.shortcut = true;
newEdge.data.turnInstruction = inData.turnInstruction;
newEdge.data.originalEdges = outData.originalEdges + inData.originalEdges;
insertedEdges.push_back( newEdge );
std::swap( newEdge.source, newEdge.target );
newEdge.data.forward = false;
newEdge.data.backward = true;
insertedEdges.push_back( newEdge );
}
}
}
}
if ( !Simulate ) {
for ( int i = insertedEdgesSize, iend = insertedEdges.size(); i < iend; i++ ) {
bool found = false;
for ( int other = i + 1 ; other < iend ; ++other ) {
if ( insertedEdges[other].source != insertedEdges[i].source )
continue;
if ( insertedEdges[other].target != insertedEdges[i].target )
continue;
if ( insertedEdges[other].data.distance != insertedEdges[i].data.distance )
continue;
if ( insertedEdges[other].data.shortcut != insertedEdges[i].data.shortcut )
continue;
insertedEdges[other].data.forward |= insertedEdges[i].data.forward;
insertedEdges[other].data.backward |= insertedEdges[i].data.backward;
found = true;
break;
}
if ( !found )
insertedEdges[insertedEdgesSize++] = insertedEdges[i];
}
insertedEdges.resize( insertedEdgesSize );
}
return true;
}
bool _DeleteIncomingEdges( _ThreadData* data, NodeID node ) {
std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear();
//find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID u = _graph->GetTarget( e );
if ( u == node )
continue;
neighbours.push_back( u );
}
//eliminate duplicate entries ( forward + backward edges )
std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
const NodeID u = neighbours[i];
_graph->DeleteEdgesTo( u, node );
}
return true;
}
bool _UpdateNeighbours( std::vector< double >* priorities, std::vector< _PriorityData >* const nodeData, _ThreadData* const data, NodeID node ) {
std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear();
//find all neighbours
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID u = _graph->GetTarget( e );
if ( u == node )
continue;
neighbours.push_back( u );
( *nodeData )[u].depth = (std::max)(( *nodeData )[node].depth + 1, ( *nodeData )[u].depth );
}
//eliminate duplicate entries ( forward + backward edges )
std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
for ( int i = 0, e = ( int ) neighbours.size(); i < e; ++i ) {
const NodeID u = neighbours[i];
( *priorities )[u] = _Evaluate( data, &( *nodeData )[u], u );
}
return true;
}
bool _IsIndependent( const std::vector< double >& priorities, const std::vector< _PriorityData >& nodeData, _ThreadData* const data, NodeID node ) {
const double priority = priorities[node];
std::vector< NodeID >& neighbours = data->neighbours;
neighbours.clear();
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( node ) ; e < _graph->EndEdges( node ) ; ++e ) {
const NodeID target = _graph->GetTarget( e );
const double targetPriority = priorities[target];
assert( targetPriority >= 0 );
//found a neighbour with lower priority?
if ( priority > targetPriority )
return false;
//tie breaking
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
return false;
neighbours.push_back( target );
}
std::sort( neighbours.begin(), neighbours.end() );
neighbours.resize( std::unique( neighbours.begin(), neighbours.end() ) - neighbours.begin() );
//examine all neighbours that are at most 2 hops away
for ( std::vector< NodeID >::const_iterator i = neighbours.begin(), lastNode = neighbours.end(); i != lastNode; ++i ) {
const NodeID u = *i;
for ( _DynamicGraph::EdgeIterator e = _graph->BeginEdges( u ) ; e < _graph->EndEdges( u ) ; ++e ) {
const NodeID target = _graph->GetTarget( e );
const double targetPriority = priorities[target];
assert( targetPriority >= 0 );
//found a neighbour with lower priority?
if ( priority > targetPriority )
return false;
//tie breaking
if ( priority == targetPriority && nodeData[node].bias < nodeData[target].bias )
return false;
}
}
return true;
}
boost::shared_ptr<_DynamicGraph> _graph;
unsigned edgeQuotionFactor;
unsigned originalQuotientFactor;
unsigned depthFactor;
};
#endif // CONTRACTOR_H_INCLUDED
-234
View File
@@ -1,234 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#include <boost/foreach.hpp>
#include "EdgeBasedGraphFactory.h"
template<>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI)
: inputRestrictions(irs), inputNodeInfoList(nI) {
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort(inputRestrictions.begin(), inputRestrictions.end(), CmpRestrictionByFrom);
#else
std::sort(inputRestrictions.begin(), inputRestrictions.end(), CmpRestrictionByFrom);
#endif
std::vector< _NodeBasedEdge > edges;
edges.reserve( 2 * inputEdges.size() );
for ( typename std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(), e = inputEdges.end(); i != e; ++i ) {
_NodeBasedEdge edge;
edge.source = i->source();
edge.target = i->target();
if(edge.source == edge.target)
continue;
edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 );
edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout();
edge.data.nameID = i->name();
edge.data.type = i->type();
edge.data.forward = i->isForward();
edge.data.backward = i->isBackward();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
std::swap( edge.source, edge.target );
if( edge.data.backward ) {
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size();
edges.push_back( edge );
}
}
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( edges.begin(), edges.end() );
#else
sort( edges.begin(), edges.end() );
#endif
_nodeBasedGraph.reset(new _NodeBasedDynamicGraph( nodes, edges ));
INFO("Converted " << inputEdges.size() << " node-based edges into " << _nodeBasedGraph->GetNumberOfEdges() << " edge-based nodes.");
}
template<>
void EdgeBasedGraphFactory::GetEdgeBasedEdges( std::vector< EdgeBasedEdge >& outputEdgeList ) {
GUARANTEE(0 == outputEdgeList.size(), "Vector passed to EdgeBasedGraphFactory::GetEdgeBasedEdges(..) is not empty");
GUARANTEE(0 != edgeBasedEdges.size(), "No edges in edge based graph");
edgeBasedEdges.swap(outputEdgeList);
}
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes) {
for(unsigned i = 0; i < edgeBasedNodes.size(); ++i)
nodes.push_back(edgeBasedNodes[i]);
}
void EdgeBasedGraphFactory::Run() {
INFO("Generating Edge based representation of input data");
std::vector<_Restriction>::iterator restrictionIterator = inputRestrictions.begin();
Percent p(_nodeBasedGraph->GetNumberOfNodes());
int numberOfResolvedRestrictions(0);
int nodeBasedEdgeCounter(0);
//Loop over all nodes u. Three nested loop look super-linear, but we are dealing with a number linear in the turns only.
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
//loop over all adjacent edge (u,v)
while(restrictionIterator->fromNode < u && inputRestrictions.end() != restrictionIterator) {
++restrictionIterator;
}
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
++nodeBasedEdgeCounter;
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
//loop over all reachable edges (v,w)
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
//if (u,v,w) is a forbidden turn, continue
bool isTurnProhibited = false;
if( u != w ) { //only add an edge if turn is not a U-turn
if(u == restrictionIterator->fromNode) {
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
do {
if( v == secondRestrictionIterator->viaNode && w == secondRestrictionIterator->toNode) {
isTurnProhibited = true;
}
++secondRestrictionIterator;
} while(u == secondRestrictionIterator->fromNode);
}
if( !isTurnProhibited ) { //only add an edge if turn is not prohibited
//new costs for edge based edge (e1, e2) = cost (e1) + tc(e1,e2)
const _NodeBasedDynamicGraph::NodeIterator edgeBasedSource = _nodeBasedGraph->GetEdgeData(e1).edgeBasedNodeID;
// INFO("edgeBasedSource: " << edgeBasedSource);
if(edgeBasedSource > _nodeBasedGraph->GetNumberOfEdges()) {
ERR("edgeBasedTarget" << edgeBasedSource << ">" << _nodeBasedGraph->GetNumberOfEdges());
}
const _NodeBasedDynamicGraph::NodeIterator edgeBasedTarget = _nodeBasedGraph->GetEdgeData(e2).edgeBasedNodeID;
// INFO("edgeBasedTarget: " << edgeBasedTarget);
if(edgeBasedTarget > _nodeBasedGraph->GetNumberOfEdges()) {
ERR("edgeBasedTarget" << edgeBasedTarget << ">" << _nodeBasedGraph->GetNumberOfEdges());
}
//incorporate turn costs, this is just a simple model and can (read: must) be extended
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
unsigned distance = (int)( _nodeBasedGraph->GetEdgeData(e1).distance *(1+std::abs((angle-180.)/180.)));
unsigned nameID = _nodeBasedGraph->GetEdgeData(e2).nameID;
short turnInstruction = AnalyzeTurn(u, v, w);
//create edge-based graph edge
//EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, EdgeWeight w, bool f, bool b, short ty)
EdgeBasedEdge newEdge(edgeBasedSource, edgeBasedTarget, v, nameID, distance, true, false, turnInstruction);
edgeBasedEdges.push_back(newEdge);
EdgeBasedNode currentNode;
if(_nodeBasedGraph->GetEdgeData(e1).type != 14) {
currentNode.nameID = _nodeBasedGraph->GetEdgeData(e1).nameID;
currentNode.lat1 = inputNodeInfoList[u].lat;
currentNode.lon1 = inputNodeInfoList[u].lon;
currentNode.lat2 = inputNodeInfoList[v].lat;
currentNode.lon2 = inputNodeInfoList[v].lon;
currentNode.id = edgeBasedSource;
currentNode.weight = _nodeBasedGraph->GetEdgeData(e1).distance;
edgeBasedNodes.push_back(currentNode);
}
} else {
++numberOfResolvedRestrictions;
}
}
}
}
p.printIncrement();
}
std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end());
edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() );
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges");
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << (double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter);
INFO("Edge-based graph obeys " << numberOfResolvedRestrictions << " turn restrictions, " << (inputRestrictions.size() - numberOfResolvedRestrictions )<< " skipped.");
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
}
short EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const {
_NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v);
_NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w);
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1);
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2);
double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
//roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) {
//Is a turn possible? If yes, we stay on the roundabout!
if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) {
//No turn possible.
return TurnInstructions.NoTurn;
} else {
return TurnInstructions.StayOnRoundAbout;
}
}
//Does turn start or end on roundabout?
if(data1.roundabout || data2.roundabout) {
//We are entering the roundabout
if( (!data1.roundabout) && data2.roundabout)
return TurnInstructions.EnterRoundAbout;
//We are leaving the roundabout
if(data1.roundabout && (!data2.roundabout) )
return TurnInstructions.LeaveRoundAbout;
}
//If street names stay the same and if we are certain that it is not a roundabout, we skip it.
if(data1.nameID == data2.nameID)
return TurnInstructions.NoTurn;
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
}
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return edgeBasedEdges.size();
}
EdgeBasedGraphFactory::~EdgeBasedGraphFactory() {
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const {
const int v1x = A.lon - C.lon;
const int v1y = A.lat - C.lat;
const int v2x = B.lon - C.lon;
const int v2y = B.lat - C.lat;
double angle = (atan2((double)v2y,v2x) - atan2((double)v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
-104
View File
@@ -1,104 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
/*
* This class constructs the edge base representation of a graph from a given node based edge list
*/
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
#include <boost/shared_ptr.hpp>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/TurnInstructions.h"
class EdgeBasedGraphFactory {
private:
struct _NodeBasedEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
bool shortcut:1;
bool forward:1;
bool backward:1;
bool roundabout:1;
short type;
} data;
struct _EdgeBasedEdgeData {
int distance;
unsigned via;
unsigned nameID;
bool forward;
bool backward;
short turnInstruction;
};
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}
bool operator==(const EdgeBasedNode & other) const {
return id == other.id;
}
int lat1;
int lat2;
int lon1;
int lon2;
NodeID id;
NodeID nameID;
unsigned weight;
};
private:
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
std::vector<_Restriction> & inputRestrictions;
std::vector<NodeInfo> & inputNodeInfoList;
std::vector<EdgeBasedEdge> edgeBasedEdges;
std::vector<EdgeBasedNode> edgeBasedNodes;
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI);
virtual ~EdgeBasedGraphFactory();
void Run();
template< class ImportEdgeT >
void GetEdgeBasedEdges( std::vector< ImportEdgeT >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
short AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
unsigned GetNumberOfNodes() const;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
-33
View File
@@ -1,33 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BASEPARSER_H_
#define BASEPARSER_H_
template<typename NodeT, typename RestrictionT, typename WayT>
class BaseParser {
public:
virtual ~BaseParser() {}
virtual bool Init() = 0;
virtual bool RegisterCallbacks(bool (*nodeCallbackPointer)(NodeT), bool (*restrictionCallbackPointer)(RestrictionT), bool (*wayCallbackPointer)(WayT), bool (*addressCallbackPointer)(NodeT, HashTable<std::string, std::string>)) = 0;
virtual bool Parse() = 0;
};
#endif /* BASEPARSER_H_ */
-293
View File
@@ -1,293 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BINARYHEAP_H_INCLUDED
#define BINARYHEAP_H_INCLUDED
//Not compatible with non contiguous node ids
#include <cassert>
#include <limits>
#include <vector>
#include <algorithm>
#include <map>
#include <google/dense_hash_map>
#include <google/sparse_hash_map>
#include <google/sparsetable>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
ArrayStorage( size_t size ) : positions( new Key[size] ) {
memset(positions, 0, size*sizeof(Key));
}
~ArrayStorage() {
delete[] positions;
}
Key &operator[]( NodeID node ) {
return positions[node];
}
void Clear() {}
private:
Key* positions;
};
template< typename NodeID, typename Key >
class MapStorage {
public:
MapStorage( size_t size = 0 ) {}
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
std::map< NodeID, Key > nodes;
};
template< typename NodeID, typename Key >
class DenseStorage {
public:
DenseStorage( size_t size = 0 ) { nodes.set_empty_key(UINT_MAX); }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
google::dense_hash_map< NodeID, Key > nodes;
};
template< typename NodeID, typename Key >
class SparseStorage {
public:
SparseStorage( size_t size = 0 ) { }
Key &operator[]( NodeID node ) {
return nodes[node];
}
void Clear() {
nodes.clear();
}
private:
google::sparse_hash_map< NodeID, Key > nodes;
};
template< typename NodeID, typename Key >
class SparseTableStorage : public google::sparsetable<NodeID> {
public:
SparseTableStorage(size_t n) : google::sparsetable<NodeID>(n){ }
void Clear() {
google::sparsetable<NodeID>::clear();
}
};
template<typename NodeID = unsigned>
struct _SimpleHeapData {
NodeID parent;
_SimpleHeapData( NodeID p ) : parent(p) { }
};
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
class BinaryHeap {
private:
BinaryHeap( const BinaryHeap& right );
void operator=( const BinaryHeap& right );
public:
typedef Weight WeightType;
typedef Data DataType;
BinaryHeap( size_t maxID )
: nodeIndex( maxID ) {
Clear();
}
void Clear() {
heap.resize( 1 );
insertedNodes.clear();
heap[0].weight = std::numeric_limits< Weight >::min();
nodeIndex.Clear();
}
Key Size() const {
return ( Key )( heap.size() - 1 );
}
void Insert( NodeID node, Weight weight, const Data &data ) {
HeapElement element;
element.index = ( NodeID ) insertedNodes.size();
element.weight = weight;
const Key key = ( Key ) heap.size();
heap.push_back( element );
insertedNodes.push_back( HeapNode( node, key, weight, data ) );
nodeIndex[node] = element.index;
Upheap( key );
CheckHeap();
}
Data& GetData( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].data;
}
Weight& GetKey( NodeID node ) {
const Key index = nodeIndex[node];
return insertedNodes[index].weight;
}
bool WasRemoved( NodeID node ) {
assert( WasInserted( node ) );
const Key index = nodeIndex[node];
return insertedNodes[index].key == 0;
}
bool WasInserted( NodeID node ) {
const Key index = nodeIndex[node];
if ( index >= ( Key ) insertedNodes.size() )
return false;
return insertedNodes[index].node == node;
}
NodeID Min() const {
assert( heap.size() > 1 );
return insertedNodes[heap[1].index].node;
}
NodeID DeleteMin() {
assert( heap.size() > 1 );
const Key removedIndex = heap[1].index;
heap[1] = heap[heap.size()-1];
heap.pop_back();
if ( heap.size() > 1 )
Downheap( 1 );
insertedNodes[removedIndex].key = 0;
CheckHeap();
return insertedNodes[removedIndex].node;
}
void DeleteAll() {
for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i )
insertedNodes[i->index].key = 0;
heap.resize( 1 );
heap[0].weight = (std::numeric_limits< Weight >::min)();
}
void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node );
const Key index = nodeIndex[node];
Key key = insertedNodes[index].key;
assert ( key >= 0 );
insertedNodes[index].weight = weight;
heap[key].weight = weight;
Upheap( key );
CheckHeap();
}
private:
class HeapNode {
public:
HeapNode() {
}
HeapNode( NodeID n, Key k, Weight w, Data d )
: node( n ), key( k ), weight( w ), data( d ) {
}
NodeID node;
Key key;
Weight weight;
Data data;
};
struct HeapElement {
Key index;
Weight weight;
};
std::vector< HeapNode > insertedNodes;
std::vector< HeapElement > heap;
IndexStorage nodeIndex;
void Downheap( Key key ) {
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key << 1;
while ( nextKey < ( Key ) heap.size() ) {
const Key nextKeyOther = nextKey + 1;
if ( ( nextKeyOther < ( Key ) heap.size() )&& ( heap[nextKey].weight > heap[nextKeyOther].weight) )
nextKey = nextKeyOther;
if ( weight <= heap[nextKey].weight )
break;
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
nextKey <<= 1;
}
heap[key].index = droppingIndex;
heap[key].weight = weight;
insertedNodes[droppingIndex].key = key;
}
void Upheap( Key key ) {
const Key risingIndex = heap[key].index;
const Weight weight = heap[key].weight;
Key nextKey = key >> 1;
while ( heap[nextKey].weight > weight ) {
assert( nextKey != 0 );
heap[key] = heap[nextKey];
insertedNodes[heap[key].index].key = key;
key = nextKey;
nextKey >>= 1;
}
heap[key].index = risingIndex;
heap[key].weight = weight;
insertedNodes[risingIndex].key = key;
}
void CheckHeap() {
#ifndef NDEBUG
for ( Key i = 2; i < (Key) heap.size(); ++i ) {
assert( heap[i].weight >= heap[i >> 1].weight );
}
#endif
}
};
#endif //#ifndef BINARYHEAP_H_INCLUDED
-98
View File
@@ -1,98 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef CONCURRENTQUEUE_H_INCLUDED
#define CONCURRENTQUEUE_H_INCLUDED
#include <queue>
#include <boost/signals2/mutex.hpp>
#include "../typedefs.h"
/*
Concurrent Queue written by Anthony Williams:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
*/
template<typename Data>
class ConcurrentQueue {
public:
ConcurrentQueue(const size_t max_size)
: max_queue_size(max_size) {
}
void push(Data const& data) {
if (size_exceeded()) {
boost::mutex::scoped_lock qf_lock(queue_full_mutex);
queue_full_cv.wait(qf_lock);
}
boost::mutex::scoped_lock lock(queue_mutex);
internal_queue.push(data);
lock.unlock();
queue_cv.notify_one();
}
bool empty() const {
return internal_queue.empty();
}
bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(queue_mutex);
if(internal_queue.empty()) {
return false;
}
popped_value=internal_queue.front();
internal_queue.pop();
queue_full_cv.notify_one();
return true;
}
void wait_and_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(queue_mutex);
while(internal_queue.empty()) {
queue_cv.wait(lock);
}
popped_value=internal_queue.front();
internal_queue.pop();
queue_full_cv.notify_one();
}
int size() const {
return static_cast<int>(internal_queue.size());
}
private:
std::queue<Data> internal_queue;
mutable boost::mutex queue_mutex;
mutable boost::mutex queue_full_mutex;
boost::condition_variable queue_cv;
boost::condition_variable queue_full_cv;
const size_t max_queue_size;
bool size_exceeded() const {
return internal_queue.size() >= max_queue_size;
}
};
#endif //#ifndef CONCURRENTQUEUE_H_INCLUDED
-237
View File
@@ -1,237 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef DYNAMICGRAPH_H_INCLUDED
#define DYNAMICGRAPH_H_INCLUDED
#include <vector>
#include <algorithm>
#include <limits>
template< typename EdgeDataT>
class DynamicGraph {
public:
typedef EdgeDataT EdgeData;
typedef unsigned NodeIterator;
typedef unsigned EdgeIterator;
class InputEdge {
public:
NodeIterator source;
NodeIterator target;
EdgeDataT data;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
};
//Constructs an empty graph with a given number of nodes.
DynamicGraph( int nodes ) : m_numNodes(nodes), m_numEdges(0) {
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
m_edges.reserve( m_numNodes * 1.2 );
m_edges.resize( m_numNodes );
}
DynamicGraph( int nodes, const std::vector< InputEdge > &graph )
{
m_numNodes = nodes;
m_numEdges = ( EdgeIterator ) graph.size();
m_nodes.reserve( m_numNodes );
m_nodes.resize( m_numNodes );
EdgeIterator edge = 0;
EdgeIterator position = 0;
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
EdgeIterator lastEdge = edge;
while ( edge < m_numEdges && graph[edge].source == node ) {
++edge;
}
m_nodes[node].firstEdge = position;
m_nodes[node].edges = edge - lastEdge;
position += m_nodes[node].edges;
}
m_edges.reserve( position * 1.2 );
m_edges.resize( position );
edge = 0;
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; i != e; ++i ) {
m_edges[i].target = graph[edge].target;
m_edges[i].data = graph[edge].data;
GUARANTEE(graph[edge].data.distance > 0, "edge: " << edge << "(" << graph[edge].source << "," << graph[edge].target << ")=" << graph[edge].data.distance);
edge++;
}
}
}
~DynamicGraph(){ }
unsigned GetNumberOfNodes() const
{
return m_numNodes;
}
unsigned GetNumberOfEdges() const
{
return m_numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const
{
return m_nodes[n].edges;
}
NodeIterator GetTarget( const EdgeIterator &e ) const
{
return NodeIterator( m_edges[e].target );
}
EdgeDataT &GetEdgeData( const EdgeIterator &e )
{
return m_edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const
{
return m_edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const
{
//assert( EndEdges( n ) - EdgeIterator( _nodes[n].firstEdge ) <= 100 );
return EdgeIterator( m_nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const
{
return EdgeIterator( m_nodes[n].firstEdge + m_nodes[n].edges );
}
//adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge( const NodeIterator &from, const NodeIterator &to, const EdgeDataT &data )
{
Node &node = m_nodes[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
if ( newFirstEdge >= m_edges.size() || !isDummy( newFirstEdge ) ) {
if ( node.firstEdge != 0 && isDummy( node.firstEdge - 1 ) ) {
node.firstEdge--;
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
} else {
EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size();
unsigned newSize = node.edges * 1.2 + 2;
EdgeIterator requiredCapacity = newSize + m_edges.size();
EdgeIterator oldCapacity = m_edges.capacity();
if ( requiredCapacity >= oldCapacity ) {
m_edges.reserve( requiredCapacity * 1.1 );
}
m_edges.resize( m_edges.size() + newSize );
for ( EdgeIterator i = 0; i < node.edges; ++i ) {
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
makeDummy( node.firstEdge + i );
}
for ( EdgeIterator i = node.edges + 1; i < newSize; i++ )
makeDummy( newFirstEdge + i );
node.firstEdge = newFirstEdge;
}
}
Edge &edge = m_edges[node.firstEdge + node.edges];
edge.target = to;
edge.data = data;
m_numEdges++;
node.edges++;
return EdgeIterator( node.firstEdge + node.edges );
}
//removes an edge. Invalidates edge iterators for the source node
void DeleteEdge( const NodeIterator source, const EdgeIterator &e ) {
Node &node = m_nodes[source];
--m_numEdges;
--node.edges;
const unsigned last = node.firstEdge + node.edges;
//swap with last edge
m_edges[e] = m_edges[last];
makeDummy( last );
}
//removes all edges (source,target)
int DeleteEdgesTo( const NodeIterator source, const NodeIterator target )
{
int deleted = 0;
for ( EdgeIterator i = BeginEdges( source ), iend = EndEdges( source ); i < iend - deleted; ++i ) {
if ( m_edges[i].target == target ) {
do {
deleted++;
m_edges[i] = m_edges[iend - deleted];
makeDummy( iend - deleted );
} while ( i < iend - deleted && m_edges[i].target == target );
}
}
#pragma omp atomic
m_numEdges -= deleted;
m_nodes[source].edges -= deleted;
return deleted;
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator &from, const NodeIterator &to ) const
{
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
if ( m_edges[i].target == to ) {
return i;
}
}
return EndEdges( from );
}
protected:
bool isDummy( EdgeIterator edge ) const
{
return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)();
}
void makeDummy( EdgeIterator edge )
{
m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)();
}
struct Node {
//index of the first edge
EdgeIterator firstEdge;
//amount of edges
unsigned edges;
};
struct Edge {
NodeIterator target;
EdgeDataT data;
};
NodeIterator m_numNodes;
EdgeIterator m_numEdges;
std::vector< Node > m_nodes;
std::vector< Edge > m_edges;
};
#endif // DYNAMICGRAPH_H_INCLUDED
-196
View File
@@ -1,196 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_
#include <stxxl.h>
#include <vector>
#include "ExtractorStructs.h"
typedef stxxl::vector<NodeID> STXXLNodeIDVector;
typedef stxxl::vector<_Node> STXXLNodeVector;
typedef stxxl::vector<_Edge> STXXLEdgeVector;
typedef stxxl::vector<_Address> STXXLAddressVector;
typedef stxxl::vector<string> STXXLStringVector;
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
struct STXXLContainers {
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
STXXLEdgeVector allEdges;
STXXLAddressVector adressVector;
STXXLStringVector nameVector;
STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector;
};
class ExtractorCallbacks{
private:
Settings settings;
StringMap * stringMap;
STXXLContainers * externalMemory;
public:
ExtractorCallbacks(STXXLContainers * ext, Settings set, StringMap * strMap){
externalMemory = ext;
settings = set;
stringMap = strMap;
}
~ExtractorCallbacks() {
}
/** warning: caller needs to take care of synchronization! */
inline bool adressFunction(_Node n, HashTable<std::string, std::string> &keyVals) {
/*
std::string housenumber(keyVals.Find("addr:housenumber"));
std::string housename(keyVals.Find("addr:housename"));
std::string street(keyVals.Find("addr:street"));
std::string state(keyVals.Find("addr:state"));
std::string country(keyVals.Find("addr:country"));
std::string postcode(keyVals.Find("addr:postcode"));
std::string city(keyVals.Find("addr:city"));
if(housenumber != "" || housename != "" || street != "") {
if(housenumber == "")
housenumber = housename;
addressVector->push_back(_Address(n, housenumber, street, state, country, postcode, city));
}
*/
return true;
}
/** warning: caller needs to take care of synchronization! */
inline bool nodeFunction(_Node &n) {
externalMemory->allNodes.push_back(n);
return true;
}
inline bool restrictionFunction(_RawRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r);
return true;
}
/** warning: caller needs to take care of synchronization! */
inline bool wayFunction(_Way &w) {
//Get the properties of the way.
std::string highway( w.keyVals.Find("highway") );
std::string name( w.keyVals.Find("name") );
std::string ref( w.keyVals.Find("ref"));
std::string oneway( w.keyVals.Find("oneway"));
std::string junction( w.keyVals.Find("junction") );
std::string route( w.keyVals.Find("route") );
double maxspeed( atoi(w.keyVals.Find("maxspeed").c_str()) );
std::string access( w.keyVals.Find("access") );
std::string accessClass( w.keyVals.Find(settings.accessTag) );
std::string man_made( w.keyVals.Find("man_made") );
std::string barrier( w.keyVals.Find("barrier") );
//Save the name of the way if it has one, ref has precedence over name tag.
if ( 0 < ref.length() )
w.name = ref;
else
if ( 0 < name.length() )
w.name = name;
if(junction == "roundabout") {
w.roundabout = true;
}
//Is the highway tag listed as usable way?
if(0 < settings[highway]) {
if(0 != maxspeed)
w.speed = maxspeed;
else
w.speed = settings[highway];
w.useful = true;
//Okay, do we have access to that way?
if(0 < access.size()) { //fastest way to check for non-empty string
//If access is forbidden, we don't want to route there.
if(access == "private" || access == "no" || access == "agricultural" || access == "forestry" || access == "delivery") { //Todo: this is still hard coded
w.access = false;
}
}
if("yes" == accessClass)
w.access = true;
else if("no" == accessClass)
w.access = false;
//Let's process oneway property, if speed profile obeys to it
if(oneway != "no" && oneway != "false" && oneway != "0" && settings.obeyOneways) {
//if oneway tag is in forward direction or if actually roundabout
if(junction == "roundabout" || oneway == "yes" || oneway == "true" || oneway == "1") {
w.direction = _Way::oneway;
} else {
if( oneway == "-1")
w.direction = _Way::opposite;
}
}
} else {
//Is the route tag listed as usable way in the profile?
if(settings[route] > 0 || settings[man_made] > 0) {
w.useful = true;
w.direction = _Way::oneway;
w.speed = settings[route];
w.direction = _Way::bidirectional;
}
}
if ( w.useful && w.access && (1 < w.path.size()) ) { //Only true if the way is specified by the speed profile
//TODO: type is not set, perhaps use a bimap'ed speed profile to do set the type correctly?
w.type = 1;
//Get the unique identifier for the street name
StringMap::const_iterator strit = stringMap->find(w.name);
if(strit == stringMap->end()) {
w.nameID = externalMemory->nameVector.size();
externalMemory->nameVector.push_back(w.name);
stringMap->insert(StringMap::value_type(w.name, w.nameID));
} else {
w.nameID = strit->second;
}
GUARANTEE(w.id != UINT_MAX, "found way with unknown type");
GUARANTEE(-1 != w.speed, "found way with unknown speed");
if ( w.direction == _Way::opposite ){
std::reverse( w.path.begin(), w.path.end() );
}
for(vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) {
externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout));
externalMemory->usedNodeIDs.push_back(w.path[n]);
}
externalMemory->usedNodeIDs.push_back(w.path[w.path.size()-1]);
//The following information is needed to identify start and end segments of restrictions
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, w.path[0], w.path[1], w.path[w.path.size()-2], w.path[w.path.size()-1]));
}
return true;
}
};
#endif /* EXTRACTORCALLBACKS_H_ */
-359
View File
@@ -1,359 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include <climits>
#include <string>
#include <boost/unordered_map.hpp>
#include "../typedefs.h"
#include "Util.h"
struct _PathData {
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
NodeID node;
unsigned nameID;
unsigned durationOfSegment;
short turnInstruction;
};
typedef boost::unordered_map<std::string, NodeID> StringMap;
struct _Node : NodeInfo{
_Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon, _id) {}
_Node() {}
static _Node min_value() {
return _Node(0,0,0);
}
static _Node max_value() {
return _Node((numeric_limits<int>::max)(), (numeric_limits<int>::max)(), (numeric_limits<unsigned int>::max)());
}
NodeID key() const {
return id;
}
};
struct _Coordinate {
int lat;
int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {}
_Coordinate (int t, int n) : lat(t) , lon(n) {}
void Reset() {
lat = INT_MIN;
lon = INT_MIN;
}
bool isSet() const {
return (INT_MIN != lat) && (INT_MIN != lon);
}
};
inline ostream & operator<<(ostream & out, const _Coordinate & c){
out << "(" << c.lat << "," << c.lon << ")";
return out;
}
struct _Way {
_Way() : id(UINT_MAX), nameID(UINT_MAX) {
direction = _Way::notSure;
speed = -1;
type = -1;
useful = false;
access = true;
roundabout = false;
}
enum {
notSure = 0, oneway, bidirectional, opposite
} direction;
unsigned id;
unsigned nameID;
std::string name;
double speed;
short type;
bool useful;
bool access;
bool roundabout;
std::vector< NodeID > path;
HashTable<std::string, std::string> keyVals;
};
struct _Address {
_Address() {}
_Address(_Node n, std::string h, std::string str, std::string sta, std::string p, std::string ci, std::string co) {
node = n;
housenumber = h;
street = str;
state = sta;
postcode = p;
city = ci;
country = co;
}
_Node node;
std::string housenumber;
std::string street;
std::string state;
std::string postcode;
std::string city;
std::string country;
};
struct _Relation {
_Relation() : type(unknown){}
enum {
unknown = 0, ferry, turnRestriction
} type;
HashTable<std::string, std::string> keyVals;
};
struct _Edge {
_Edge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false) {};
_Edge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false) { }
_Edge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra) { }
NodeID start;
NodeID target;
short type;
short direction;
double speed;
unsigned nameID;
bool isRoundabout;
_Coordinate startCoord;
_Coordinate targetCoord;
static _Edge min_value() {
return _Edge(0,0);
}
static _Edge max_value() {
return _Edge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
}
};
struct _Restriction {
NodeID viaNode;
NodeID fromNode;
NodeID toNode;
struct bits { //mostly unused
char isOnly:1;
char unused1:1;
char unused2:1;
char unused3:1;
char unused4:1;
char unused5:1;
char unused6:1;
char unused7:1;
} flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { }
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) {
flags.isOnly = isOnly;
}
};
inline bool CmpRestrictionByFrom ( _Restriction a, _Restriction b) { return (a.fromNode < b.fromNode); }
struct _RawRestrictionContainer {
_Restriction restriction;
EdgeID fromWay;
EdgeID toWay;
unsigned viaWay;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaWay(vw) { restriction.viaNode = vn;}
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaWay(UINT_MAX) { restriction.flags.isOnly = isOnly;}
static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)());
}
static _RawRestrictionContainer max_value() {
return _RawRestrictionContainer((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
}
};
struct CmpRestrictionContainerByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.fromWay < b.fromWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
};
struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.toWay < b.toWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
};
struct _WayIDStartAndEndEdge {
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
_WayIDStartAndEndEdge() : wayID(UINT_MAX), firstStart(UINT_MAX), firstTarget(UINT_MAX), lastStart(UINT_MAX), lastTarget(UINT_MAX) {}
_WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {}
static _WayIDStartAndEndEdge min_value() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)());
}
static _WayIDStartAndEndEdge max_value() {
return _WayIDStartAndEndEdge((numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)(), (numeric_limits<unsigned>::max)());
}
};
struct CmpWayStartAndEnd : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
typedef _WayIDStartAndEndEdge value_type;
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const {
return a.wayID < b.wayID;
}
value_type max_value() {
return _WayIDStartAndEndEdge::max_value();
}
value_type min_value() {
return _WayIDStartAndEndEdge::min_value();
}
};
struct Settings {
Settings() : obeyPollards(true), obeyOneways(true), useRestrictions(true), accessTag("motorcar") {}
StringMap speedProfile;
int operator[](const string & param) const {
if(speedProfile.find(param) == speedProfile.end())
return 0;
else
return speedProfile.at(param);
}
bool obeyPollards;
bool obeyOneways;
bool useRestrictions;
string accessTag;
};
struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
typedef NodeID value_type;
bool operator () (const NodeID & a, const NodeID & b) const {
return a < b;
}
value_type max_value() {
return 0xffffffff;
}
value_type min_value() {
return 0x0;
}
};
struct CmpNodeByID : public std::binary_function<_Node, _Node, bool> {
typedef _Node value_type;
bool operator () (const _Node & a, const _Node & b) const {
return a.id < b.id;
}
value_type max_value() {
return _Node::max_value();
}
value_type min_value() {
return _Node::min_value();
}
};
struct CmpEdgeByStartID : public std::binary_function<_Edge, _Edge, bool>
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const {
return a.start < b.start;
}
value_type max_value() {
return _Edge::max_value();
}
value_type min_value() {
return _Edge::min_value();
}
};
struct CmpEdgeByTargetID : public std::binary_function<_Edge, _Edge, bool>
{
typedef _Edge value_type;
bool operator () (const _Edge & a, const _Edge & b) const
{
return a.target < b.target;
}
value_type max_value()
{
return _Edge::max_value();
}
value_type min_value()
{
return _Edge::min_value();
}
};
inline double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) {
assert(lat1 != INT_MIN);
assert(lon1 != INT_MIN);
assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN);
static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
///Earth's quatratic mean radius for WGS-84
static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
double latitudeArc = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD;
double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD;
double latitudeH = sin( latitudeArc * 0.5 );
latitudeH *= latitudeH;
double lontitudeH = sin( longitudeArc * 0.5 );
lontitudeH *= lontitudeH;
double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD );
double distanceArc = 2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) );
return EARTH_RADIUS_IN_METERS * distanceArc;
}
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
inline string GetRandomString() {
char s[128];
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 127; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[127] = 0;
return string(s);
}
#endif /* EXTRACTORSTRUCTS_H_ */
-78
View File
@@ -1,78 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef GRIDEDGE_H_
#define GRIDEDGE_H_
struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX) {}
NodeID edgeBasedNode;
NodeID nameID;
int weight;
_Coordinate startCoord;
_Coordinate targetCoord;
};
struct GridEntry {
GridEntry() : fileIndex(UINT_MAX), ramIndex(UINT_MAX){}
GridEntry(_GridEdge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
_GridEdge edge;
unsigned fileIndex;
unsigned ramIndex;
bool operator< ( const GridEntry& right ) const {
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
}
bool operator==( const GridEntry& right ) const {
return right.edge.edgeBasedNode == edge.edgeBasedNode;
}
};
struct CompareGridEdgeDataByFileIndex
{
bool operator () (const GridEntry & a, const GridEntry & b) const
{
return a.fileIndex < b.fileIndex;
}
};
struct CompareGridEdgeDataByRamIndex
{
typedef GridEntry value_type;
bool operator () (const GridEntry & a, const GridEntry & b) const
{
return a.ramIndex < b.ramIndex;
}
value_type max_value()
{
GridEntry e;
e.ramIndex = (1024*1024) - 1;
return e;
}
value_type min_value()
{
GridEntry e;
e.ramIndex = 0;
return e;
}
};
#endif /* GRIDEDGE_H_ */
-78
View File
@@ -1,78 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
Created on: 18.11.2010
Author: dennis
*/
#ifndef HASHTABLE_H_
#define HASHTABLE_H_
#include <boost/unordered_map.hpp>
template<typename keyT, typename valueT>
class HashTable {
typedef boost::unordered_map<keyT, valueT> MyHashTable;
public:
typedef typename boost::unordered_map<keyT, valueT>::const_iterator MyIterator;
typedef MyIterator iterator;
HashTable() { }
HashTable(const unsigned size) {
table.resize(size);
}
void Add(const keyT& key, const valueT& value){
table[key] = value;
}
void Set(const keyT& key, const valueT& value){
table[key] = value;
}
valueT Find(const keyT& key) {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
}
bool Holds(const keyT& key) {
if(table.find(key) == table.end())
return false;
return true;
}
void EraseAll() {
if(table.size() > 0)
table.clear();
}
inline
valueT & operator[] (keyT key) {
return table[key];
}
unsigned Size() const {
return table.size();
}
MyIterator begin() const {
return table.begin();
}
MyIterator end() const {
return table.end();
}
private:
MyHashTable table;
};
#endif /* HASHTABLE_H_ */
-136
View File
@@ -1,136 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EDGE_H
#define EDGE_H
#include <cassert>
class NodeBasedEdge {
public:
bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
if (weight() == e.weight()) {
return (isForward() && isBackward() &&
((! e.isForward()) || (! e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
/** Default constructor. target and weight are set to 0.*/
NodeBasedEdge() :
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false) { assert(false); } //shall not be used.
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra) { assert(ty >= 0); }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; }
short type() const { assert(_type >= 0); return _type; }
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
bool isRoundabout() const { return _roundabout; }
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
bool forward;
bool backward;
short _type;
bool _roundabout;
};
class EdgeBasedEdge {
public:
bool operator< (const EdgeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
if (weight() == e.weight()) {
return (isForward() && isBackward() &&
((! e.isForward()) || (! e.isBackward())));
}
return (weight() < e.weight());
}
return (target() < e.target());
}
return (source() < e.source());
}
template<class EdgeT>
EdgeBasedEdge(const EdgeT & myEdge ) :
_source(myEdge.source),
_target(myEdge.target),
_via(myEdge.data.via),
_nameID1(myEdge.data.nameID),
_weight(myEdge.data.distance),
_forward(myEdge.data.forward),
_backward(myEdge.data.backward),
_turnInstruction(myEdge.data.turnInstruction) { }
/** Default constructor. target and weight are set to 0.*/
EdgeBasedEdge() :
_source(0), _target(0), _via(0), _nameID1(0), _weight(0), _forward(0), _backward(0), _turnInstruction(0) { assert(false); } //shall not be used.
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, EdgeWeight w, bool f, bool b, short ty) :
_source(s), _target(t), _via(v), _nameID1(n1), _weight(w), _forward(f), _backward(b), _turnInstruction(ty) { assert(ty >= 0); }
NodeID target() const {return _target; }
NodeID source() const {return _source; }
EdgeWeight weight() const {return _weight; }
NodeID via() const { return _via; }
short turnInstruction() const { assert(_turnInstruction >= 0); return _turnInstruction; }
bool isBackward() const { return _backward; }
bool isForward() const { return _forward; }
unsigned getNameIDOfTurnTarget() const { return _nameID1; }
NodeID _source;
NodeID _target;
NodeID _via;
unsigned _nameID1;
EdgeWeight _weight;
bool _forward;
bool _backward;
short _turnInstruction;
};
struct MinimalEdgeData {
public:
EdgeWeight distance;
bool forward;
bool backward;
};
typedef NodeBasedEdge ImportEdge;
#endif // EDGE_H
-94
View File
@@ -1,94 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef INPUTREADERFACTORY_H
#define INPUTREADERFACTORY_H
#include <bzlib.h>
#include <libxml/xmlreader.h>
struct BZ2Context {
FILE* file;
BZFILE* bz2;
int error;
int nUnused;
char unused[BZ_MAX_UNUSED];
};
int readFromBz2Stream( void* pointer, char* buffer, int len ) {
void *unusedTmpVoid=NULL;
char *unusedTmp=NULL;
BZ2Context* context = (BZ2Context*) pointer;
int read = 0;
while(0 == read && !(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file))) {
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
if(BZ_OK == context->error) {
return read;
} else if(BZ_STREAM_END == context->error) {
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadGetUnused" << endl; exit(-1);};
unusedTmp = (char*)unusedTmpVoid;
for(int i=0;i<context->nUnused;i++) {
context->unused[i] = unusedTmp[i];
}
BZ2_bzReadClose(&context->error, context->bz2);
if(BZ_OK != context->error) { cerr << "Could not BZ2_bzReadClose" << endl; exit(-1);};
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if(0 == context->nUnused && feof(context->file)) {
return read;
} else {
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused);
if(NULL == context->bz2){ cerr << "Could not open file" << endl; exit(-1);};
}
} else { cerr << "Could not read bz2 file" << endl; exit(-1); }
}
return read;
}
int closeBz2Stream( void *pointer )
{
BZ2Context* context = (BZ2Context*) pointer;
fclose( context->file );
delete context;
return 0;
}
xmlTextReaderPtr inputReaderFactory( const char* name )
{
std::string inputName(name);
if(inputName.find(".osm.bz2")!=string::npos)
{
BZ2Context* context = new BZ2Context();
context->error = false;
context->file = fopen( name, "r" );
int error;
context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, context->unused, context->nUnused );
if ( context->bz2 == NULL || context->file == NULL ) {
delete context;
return NULL;
}
return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 );
} else {
return xmlNewTextReaderFilename(name);
}
}
#endif // INPUTREADERFACTORY_H
-128
View File
@@ -1,128 +0,0 @@
#include <climits>
#include <google/sparse_hash_map>
#include <iostream>
#include <list>
#include <vector>
template < class T >
struct Countfn {
unsigned long operator()( const T &x ) { return 1; }
};
template< class Key, class Data, class Sizefn = Countfn< Data > > class LRUCache {
public:
typedef std::list< std::pair< Key, Data > > List; ///< Main cache storage typedef
typedef typename List::iterator List_Iter; ///< Main cache iterator
typedef typename List::const_iterator List_cIter; ///< Main cache iterator (const)
typedef std::vector< Key > Key_List; ///< List of keys
typedef typename Key_List::iterator Key_List_Iter; ///< Main cache iterator
typedef typename Key_List::const_iterator Key_List_cIter; ///< Main cache iterator (const)
typedef google::sparse_hash_map< Key, List_Iter > Map; ///< Index typedef
typedef std::pair< Key, List_Iter > Pair; ///< Pair of Map elements
typedef typename Map::iterator Map_Iter; ///< Index iterator
typedef typename Map::const_iterator Map_cIter; ///< Index iterator (const)
private:
List _list; ///< Main cache storage
Map _index; ///< Cache storage index
unsigned long _max_size; ///< Maximum abstract size of the cache
unsigned long _curr_size; ///< Current abstract size of the cache
public:
LRUCache( const unsigned long Size ) : _max_size( Size ), _curr_size( 0 ) {
_index.set_deleted_key(UINT_MAX);
}
~LRUCache() { clear(); }
inline const unsigned long size( void ) const { return _curr_size; }
inline const unsigned long max_size( void ) const { return _max_size; }
/// Clears all storage and indices.
void clear( void ) {
_list.clear();
_index.clear();
};
inline bool exists( const Key &key ) const {
return _index.find( key ) != _index.end();
}
inline void remove( const Key &key ) {
Map_Iter miter = _index.find( key );
if( miter == _index.end() ) return;
_remove( miter );
}
inline void touch( const Key &key ) {
_touch( key );
}
inline Data *fetch_ptr( const Key &key, bool touch = true ) {
Map_Iter miter = _index.find( key );
if( miter == _index.end() ) return NULL;
_touch( key );
return &(miter->second->second);
}
inline bool fetch( const Key &key, Data &data, bool touch_data = true ) {
Map_Iter miter = _index.find( key );
if( miter == _index.end() ) return false;
if( touch_data )
_touch( key );
data = miter->second->second;
return true;
}
inline void insert( const Key &key, const Data data ) {
// Touch the key, if it exists, then replace the content.
Map_Iter miter = _touch( key );
if( miter != _index.end() )
_remove( miter );
// Ok, do the actual insert at the head of the list
_list.push_front( std::make_pair( key, data ) );
List_Iter liter = _list.begin();
// Store the index
_index.insert( std::make_pair( key, liter ) );
_curr_size += Sizefn()( data );
// Check to see if we need to remove an element due to exceeding max_size
while( _curr_size > _max_size ) {
std::cout << "removing element " << std::endl;
// Remove the last element.
liter = _list.end();
--liter;
_remove( liter->first );
}
}
inline const Key_List get_all_keys( void ) {
Key_List ret;
for( List_cIter liter = _list.begin(); liter != _list.end(); liter++ )
ret.push_back( liter->first );
return ret;
}
private:
inline Map_Iter _touch( const Key &key ) {
Map_Iter miter = _index.find( key );
if( miter == _index.end() ) return miter;
// Move the found node to the head of the list.
_list.splice( _list.begin(), _list, miter->second );
return miter;
}
inline void _remove( const Map_Iter &miter ) {
_curr_size -= Sizefn()( miter->second->second );
_list.erase( miter->second );
_index.erase( miter );
}
inline void _remove( const Key &key ) {
Map_Iter miter = _index.find( key );
_remove( miter );
}
};
-635
View File
@@ -1,635 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NNGRID_H_
#define NNGRID_H_
#include <algorithm>
#include <cassert>
#include <cmath>
#include <fstream>
#include <limits>
#include <vector>
#include <stxxl.h>
#ifdef _OPENMP
#include <omp.h>
#endif
#ifdef _WIN32
#include <math.h>
#endif
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <google/dense_hash_map>
#include "ExtractorStructs.h"
#include "GridEdge.h"
#include "LRUCache.h"
#include "Percent.h"
#include "PhantomNodes.h"
#include "Util.h"
#include "StaticGraph.h"
static const unsigned MAX_CACHE_ELEMENTS = 1000;
namespace NNGrid{
static unsigned GetFileIndexForLatLon(const int lt, const int ln) {
double lat = lt/100000.;
double lon = ln/100000.;
double x = ( lon + 180.0 ) / 360.0;
double y = ( lat + 180.0 ) / 360.0;
assert( x<=1.0 && x >= 0);
assert( y<=1.0 && y >= 0);
unsigned line = 1073741824.0*y;
line = line - (line % 32768);
assert(line % 32768 == 0);
unsigned column = 32768.*x;
unsigned fileIndex = line+column;
return fileIndex;
}
static unsigned GetRAMIndexFromFileIndex(const int fileIndex) {
unsigned fileLine = fileIndex / 32768;
fileLine = fileLine / 32;
fileLine = fileLine * 1024;
unsigned fileColumn = (fileIndex % 32768);
fileColumn = fileColumn / 32;
unsigned ramIndex = fileLine + fileColumn;
assert(ramIndex < 1024*1024);
return ramIndex;
}
static inline int signum(int x){
return (x > 0) ? 1 : (x < 0) ? -1 : 0;
}
static void GetIndicesByBresenhamsAlgorithm(int xstart,int ystart,int xend,int yend, std::vector<std::pair<unsigned, unsigned> > &indexList) {
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
dx = xend - xstart;
dy = yend - ystart;
incx = signum(dx);
incy = signum(dy);
if(dx<0) dx = -dx;
if(dy<0) dy = -dy;
if (dx>dy) {
pdx=incx; pdy=0;
ddx=incx; ddy=incy;
es =dy; el =dx;
} else {
pdx=0; pdy=incy;
ddx=incx; ddy=incy;
es =dx; el =dy;
}
x = xstart;
y = ystart;
err = el/2;
{
int fileIndex = (y-1)*32768 + x;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
indexList.push_back(std::make_pair(fileIndex, ramIndex));
}
for(t=0; t<el; ++t) {
err -= es;
if(err<0) {
err += el;
x += ddx;
y += ddy;
} else {
x += pdx;
y += pdy;
}
{
int fileIndex = (y-1)*32768 + x;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
indexList.push_back(std::make_pair(fileIndex, ramIndex));
}
}
}
static void GetListOfIndexesForEdgeAndGridSize(_Coordinate& start, _Coordinate& target, std::vector<std::pair<unsigned, unsigned> > &indexList) {
double lat1 = start.lat/100000.;
double lon1 = start.lon/100000.;
double x1 = ( lon1 + 180.0 ) / 360.0;
double y1 = ( lat1 + 180.0 ) / 360.0;
double lat2 = target.lat/100000.;
double lon2 = target.lon/100000.;
double x2 = ( lon2 + 180.0 ) / 360.0;
double y2 = ( lat2 + 180.0 ) / 360.0;
GetIndicesByBresenhamsAlgorithm(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
}
static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid {
public:
NNGrid() /*: cellCache(500), fileCache(500)*/ {
ramIndexTable.resize((1024*1024), UINT_MAX);
if( WriteAccess) {
entries = new stxxl::vector<GridEntry>();
}
}
NNGrid(const char* rif, const char* _i, unsigned numberOfThreads = omp_get_num_procs()) /*: cellCache(500), fileCache(500) */{
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i);
ramIndexTable.resize((1024*1024), UINT_MAX);
ramInFile.open(rif, std::ios::in | std::ios::binary);
entries = NULL;
}
~NNGrid() {
if(ramInFile.is_open()) ramInFile.close();
if (WriteAccess) {
delete entries;
}
if(localStream.get() && localStream->is_open()) {
localStream->close();
}
}
void OpenIndexFiles() {
assert(ramInFile.is_open());
for(int i = 0; i < 1024*1024; ++i) {
unsigned temp;
ramInFile.read((char*)&temp, sizeof(unsigned));
ramIndexTable[i] = temp;
}
ramInFile.close();
}
template<typename EdgeT, typename NodeInfoT>
void ConstructGrid(std::vector<EdgeT> & edgeList, vector<NodeInfoT> * int2ExtNodeMap, char * ramIndexOut, char * fileIndexOut) {
Percent p(edgeList.size());
for(NodeID i = 0; i < edgeList.size(); ++i) {
p.printIncrement();
EdgeT & edge = edgeList[i];
int slat = 100000*lat2y(edge.lat1/100000.);
int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2;
AddEdge( _GridEdge(
edge.id, edge.nameID, edge.weight,
_Coordinate(slat, slon),
_Coordinate(tlat, tlon) )
);
}
double timestamp = get_timestamp();
//create index file on disk, old one is over written
indexOutFile.open(fileIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
cout << "sorting grid data consisting of " << entries->size() << " edges..." << flush;
//sort entries
stxxl::sort(entries->begin(), entries->end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
cout << "ok in " << (get_timestamp() - timestamp) << "s" << endl;
std::vector<GridEntry> entriesInFileWithRAMSameIndex;
unsigned indexInRamTable = entries->begin()->ramIndex;
unsigned lastPositionInIndexFile = 0;
unsigned numberOfUsedCells = 0;
unsigned maxNumberOfRAMCellElements = 0;
cout << "writing data ..." << flush;
p.reinit(entries->size());
for(stxxl::vector<GridEntry>::iterator vt = entries->begin(); vt != entries->end(); ++vt) {
p.printIncrement();
if(vt->ramIndex != indexInRamTable) {
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
if(entriesInFileWithRAMSameIndex.size() > maxNumberOfRAMCellElements)
maxNumberOfRAMCellElements = entriesInFileWithRAMSameIndex.size();
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
lastPositionInIndexFile += numberOfBytesInCell;
entriesInFileWithRAMSameIndex.clear();
indexInRamTable = vt->ramIndex;
numberOfUsedCells++;
}
entriesInFileWithRAMSameIndex.push_back(*vt);
}
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
numberOfUsedCells++;
entriesInFileWithRAMSameIndex.clear();
assert(entriesInFileWithRAMSameIndex.size() == 0);
for(int i = 0; i < 1024*1024; ++i) {
if(ramIndexTable[i] != UINT_MAX) {
numberOfUsedCells--;
}
}
assert(numberOfUsedCells == 0);
//close index file
indexOutFile.close();
//Serialize RAM Index
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM
for(int i = 0; i < 1024*1024; ++i)
ramFile.write((char *)&ramIndexTable[i], sizeof(unsigned) );
//close ram index file
ramFile.close();
}
bool GetEdgeBasedStartNode(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(coord.lat)/100000.)), coord.lon);
/** search for point on edge next to source */
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++){
GetContentsOfFileBucket(fileIndex+i+j, candidates);
}
}
_Coordinate tmp;
double dist = numeric_limits<double>::max();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
nodesOfEdge.edgeBasedNode = candidate.edgeBasedNode;
nodesOfEdge.ratio = r;
dist = tmpDist;
nodesOfEdge.projectedPoint.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
nodesOfEdge.projectedPoint.lon = tmp.lon;
}
}
if(dist != (numeric_limits<double>::max)()) {
return true;
}
return false;
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
bool foundNode = false;
_Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++){
GetContentsOfFileBucket(fileIndex+i+j, candidates);
}
}
_GridEdge smallestEdge;
_Coordinate tmp, newEndpoint;
double dist = (numeric_limits<double>::max)();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs((int)candidate.edgeBasedNode-(int)resultNode.edgeBasedNode)) {
resultNode.weight2 = candidate.weight;
/* if(resultNode.weight1 != resultNode.weight2) {
ERR("w1: " << resultNode.weight1 << ", w2: " << resultNode.weight2);
assert(false);
}*/
if(candidate.edgeBasedNode < resultNode.edgeBasedNode) {
resultNode.edgeBasedNode = candidate.edgeBasedNode;
std::swap(resultNode.weight1, resultNode.weight2);
}
}
if(tmpDist < dist) {
resultNode.Reset();
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
dist = tmpDist;
resultNode.location.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
resultNode.location.lon = tmp.lon;
foundNode = true;
smallestEdge = candidate;
newEndpoint = tmp;
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << LengthOfVector(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << LengthOfVector(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected ? "yes" : "no"));
// }
double ratio = std::min(1., LengthOfVector(smallestEdge.startCoord, newEndpoint)/LengthOfVector(smallestEdge.startCoord, smallestEdge.targetCoord) );
assert(ratio >= 0 && ratio <=1);
// INFO("Old weight1: " << resultNode.weight1 << ", old weight2: " << resultNode.weight2);
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 *= (1-ratio);
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2);
}
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts) {
routingStarts.Reset();
return (FindPhantomNodeForCoordinate( start, routingStarts.startPhantom) &&
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom) );
}
void FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
std::vector<_GridEdge> candidates;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++) {
GetContentsOfFileBucket(fileIndex+i+j, candidates);
}
}
_Coordinate tmp;
double dist = (numeric_limits<double>::max)();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(inputCoordinate, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate = tmp;
}
}
outputCoordinate.lat = 100000*(y2lat(static_cast<double>(outputCoordinate.lat)/100000.));
}
void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++) {
GetContentsOfFileBucket(fileIndex+i+j, candidates);
}
}
_Coordinate tmp;
double dist = (numeric_limits<double>::max)();
BOOST_FOREACH(_GridEdge candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
outputCoordinate.lon = tmp.lon;
}
}
}
private:
inline double LengthOfVector(const _Coordinate & c1, const _Coordinate & c2) {
double length1 = std::sqrt(c1.lat/100000.*c1.lat/100000. + c1.lon/100000.*c1.lon/100000.);
double length2 = std::sqrt(c2.lat/100000.*c2.lat/100000. + c2.lon/100000.*c2.lon/100000.);
return std::fabs(length1-length2);
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) {
return (std::fabs(d1 - d2) < 0.000000001);
}
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset ) {
vector<char> * tmpBuffer = new vector<char>();
tmpBuffer->resize(32*32*4096,0);
unsigned indexIntoTmpBuffer = 0;
unsigned numberOfWrittenBytes = 0;
assert(indexOutFile.is_open());
vector<unsigned> cellIndex;
cellIndex.resize(32*32,UINT_MAX);
google::dense_hash_map< unsigned, unsigned > * cellMap = new google::dense_hash_map< unsigned, unsigned >(1024);
cellMap->set_empty_key(UINT_MAX);
unsigned ramIndex = entriesWithSameRAMIndex.begin()->ramIndex;
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
for(int i = 0; i < 32; i++) {
for(int j = 0; j < 32; j++) {
unsigned fileIndex = lineBase + i*32768 + columnBase+j;
unsigned cellIndex = i*32+j;
cellMap->insert(std::make_pair(fileIndex, cellIndex));
}
}
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
}
//sort & unique
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
std::vector<GridEntry>::iterator uniqueEnd = std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end());
//traverse each file bucket and write its contents to disk
std::vector<GridEntry> entriesWithSameFileIndex;
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
for(std::vector<GridEntry>::iterator it = entriesWithSameRAMIndex.begin(); it != uniqueEnd; it++) {
assert(cellMap->find(it->fileIndex) != cellMap->end() ); //asserting that file index belongs to cell index
if(it->fileIndex != fileIndex) {
// start in cellIndex vermerken
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap->find(localFileIndex)->second;
/*int localRamIndex = */GetRAMIndexFromFileIndex(localFileIndex);
assert(cellMap->find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap->end());
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
}
GridEntry data = *it;
entriesWithSameFileIndex.push_back(data);
fileIndex = it->fileIndex;
}
assert(cellMap->find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap->end());
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap->find(localFileIndex)->second;
/*int localRamIndex = */GetRAMIndexFromFileIndex(localFileIndex);
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
assert(entriesWithSameFileIndex.size() == 0);
for(int i = 0; i < 32*32; i++) {
indexOutFile.write((char *)&cellIndex[i], sizeof(unsigned));
numberOfWrittenBytes += sizeof(unsigned);
}
//write contents of tmpbuffer to disk
for(unsigned i = 0; i < indexIntoTmpBuffer; i++) {
indexOutFile.write(&(tmpBuffer->at(i)), sizeof(char));
numberOfWrittenBytes += sizeof(char);
}
delete tmpBuffer;
delete cellMap;
return numberOfWrittenBytes;
}
unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, vector<char> * tmpBuffer, const unsigned index) {
tmpBuffer->resize(tmpBuffer->size()+(sizeof(_GridEdge)*vectorWithSameFileIndex.size()) );
unsigned counter = 0;
unsigned max = UINT_MAX;
for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; i++) {
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
}
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
BOOST_FOREACH(GridEntry entry, vectorWithSameFileIndex) {
char * data = (char *)&(entry.edge);
for(unsigned i = 0; i < sizeof(_GridEdge); ++i) {
tmpBuffer->at(index+counter) = data[i];
++counter;
}
}
char * umax = (char *) &max;
for(unsigned i = 0; i < sizeof(unsigned); i++) {
tmpBuffer->at(index+counter) = umax[i];
counter++;
}
vectorWithSameFileIndex.clear();
std::vector<GridEntry>().swap(vectorWithSameFileIndex);
return counter;
}
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result) {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == UINT_MAX) {
return;
}
std::vector<unsigned> cellIndex;
cellIndex.resize(32*32);
google::dense_hash_map< unsigned, unsigned > cellMap(1024);
cellMap.set_empty_key(UINT_MAX);
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
for(int i = 0; i < 32; i++) {
for(int j = 0; j < 32; j++) {
unsigned fileIndex = lineBase + i*32768 + columnBase+j;
unsigned cellIndex = i*32+j;
cellMap.insert(std::make_pair(fileIndex, cellIndex));
}
}
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
localStream->seekg(startIndexInFile);
localStream->read((char*) &cellIndex[0], 32*32*sizeof(unsigned));
assert(cellMap.find(fileIndex) != cellMap.end());
if(cellIndex[cellMap.find(fileIndex)->second] == UINT_MAX) {
return;
}
const unsigned position = cellIndex[cellMap.find(fileIndex)->second] + 32*32*sizeof(unsigned) ;
localStream->seekg(position);
_GridEdge gridEdge;
do {
localStream->read((char *)&(gridEdge), sizeof(_GridEdge));
if(localStream->eof() || gridEdge.edgeBasedNode == UINT_MAX)
break;
result.push_back(gridEdge);
} while(true);
}
void AddEdge(_GridEdge edge) {
std::vector<std::pair<unsigned, unsigned> > indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
for(unsigned i = 0; i < indexList.size(); ++i) {
entries->push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
}
}
double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r) {
const double x = (double)inputPoint.lat;
const double y = (double)inputPoint.lon;
const double a = (double)source.lat;
const double b = (double)source.lon;
const double c = (double)target.lat;
const double d = (double)target.lon;
double p,q,mX,nY;
if(c != a){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1 + m*m);
q = b + m*(p - a);
}
else{
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
*r = mX;
if(*r<=0){
nearest.lat = source.lat;
nearest.lon = source.lon;
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(*r >= 1){
nearest.lat = target.lat;
nearest.lon = target.lon;
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
nearest.lat = p;
nearest.lon = q;
return (p-x)*(p-x) + (q-y)*(q-y);
}
ofstream indexOutFile;
ifstream ramInFile;
stxxl::vector<GridEntry> * entries;
std::vector<unsigned> ramIndexTable; //4 MB for first level index in RAM
std::string iif;
// LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache;
};
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
typedef NNGrid::NNGrid<true > WritableGrid;
#endif /* NNGRID_H_ */
-68
View File
@@ -1,68 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef _NODE_COORDS_H
#define _NODE_COORDS_H
#include <cassert>
#include <cstddef>
#include <climits>
#include "../typedefs.h"
template<typename NodeT>
struct NodeCoords {
typedef unsigned key_type; //type of NodeID
typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {}
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
int lat;
int lon;
NodeT id;
static NodeCoords<NodeT> min_value()
{
return NodeCoords<NodeT>(-90*100000,-180*100000,numeric_limits<NodeT>::min());
}
static NodeCoords<NodeT> max_value()
{
return NodeCoords<NodeT>(90*100000, 180*100000, numeric_limits<NodeT>::max());
}
value_type operator[](size_t n) const {
switch(n) {
case 1:
return lat;
break;
case 0:
return lon;
break;
default:
assert(false);
return UINT_MAX;
break;
}
assert(false);
return UINT_MAX;
}
};
#endif //_NODE_COORDS_H
-90
View File
@@ -1,90 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_
#include <fstream>
#include <iostream>
#include <vector>
#include "../typedefs.h"
#include "NNGrid.h"
#include "PhantomNodes.h"
class NodeInformationHelpDesk{
public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, unsigned _numberOfNodes) : numberOfNodes(_numberOfNodes) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
int2ExtNodeMap = new vector<_Coordinate>();
int2ExtNodeMap->reserve(numberOfNodes);
assert(0 == int2ExtNodeMap->size());
}
~NodeInformationHelpDesk() {
delete int2ExtNodeMap;
delete readOnlyGrid;
}
void initNNGrid(ifstream& in) {
while(!in.eof()) {
NodeInfo b;
in.read((char *)&b, sizeof(b));
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
}
in.close();
readOnlyGrid->OpenIndexFiles();
}
inline int getLatitudeOfNode(const NodeID node) const {
return int2ExtNodeMap->at(node).lat;
}
inline int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
NodeID getNumberOfNodes() const { return numberOfNodes; }
NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); }
inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) {
readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode);
}
inline bool FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & phantomNodes) {
readOnlyGrid->FindRoutingStarts(start, target, phantomNodes);
return true;
}
inline bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
return readOnlyGrid->GetEdgeBasedStartNode(coord, nodesOfEdge);
}
inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){
readOnlyGrid->FindNearestPointOnEdge(input, output);
}
private:
vector<_Coordinate> * int2ExtNodeMap;
ReadOnlyGrid * readOnlyGrid;
unsigned numberOfNodes;
};
#endif /*NODEINFORMATIONHELPDESK_H_*/
-535
View File
@@ -1,535 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef PBFPARSER_H_
#define PBFPARSER_H_
#include <zlib.h>
#include "BaseParser.h"
#include "pbf-proto/fileformat.pb.h"
#include "pbf-proto/osmformat.pb.h"
#include "../typedefs.h"
#include "HashTable.h"
#include "ExtractorStructs.h"
#include "ConcurrentQueue.h"
class PBFParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
enum EntityType {
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8
} ;
enum Endianness {
LittleEndian = 1,
BigEndian = 2
};
struct _ThreadData {
int currentGroupID;
int currentEntityID;
short entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
OSMPBF::HeaderBlock PBFHeaderBlock;
OSMPBF::PrimitiveBlock PBFprimitiveBlock;
std::vector<char> charBuffer;
};
public:
PBFParser(const char * fileName)
: threadDataQueue( new ConcurrentQueue<_ThreadData*>(25) ) { /* Max 25 items in queue */
GOOGLE_PROTOBUF_VERIFY_VERSION;
input.open(fileName, std::ios::in | std::ios::binary);
if (!input) {
std::cerr << fileName << ": File not found." << std::endl;
}
blockCount = 0;
groupCount = 0;
//Dummy initialization
wayCallback = NULL; nodeCallback = NULL;
addressCallback = NULL; restrictionCallback = NULL;
}
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*restrictionCallbackPointer)(_RawRestrictionContainer), bool (*wayCallbackPointer)(_Way),bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
nodeCallback = *nodeCallbackPointer;
wayCallback = *wayCallbackPointer;
restrictionCallback = *restrictionCallbackPointer;
addressCallback = *addressCallbackPointer;
return true;
}
~PBFParser() {
if(input.is_open())
input.close();
// Clean up any leftover ThreadData objects in the queue
_ThreadData* td;
while (threadDataQueue->try_pop(td)) {
delete td;
}
delete threadDataQueue;
google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG
std::cout << "[info] blocks: " << blockCount << std::endl;
std::cout << "[info] groups: " << groupCount << std::endl;
#endif
}
bool Init() {
_ThreadData initData;
/** read Header */
if(!readPBFBlobHeader(input, &initData)) {
return false;
}
if(readBlob(input, &initData)) {
if(!initData.PBFHeaderBlock.ParseFromArray(&(initData.charBuffer[0]), initData.charBuffer.size() ) ) {
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
for(int i = 0; i < initData.PBFHeaderBlock.required_features_size(); i++) {
const std::string& feature = initData.PBFHeaderBlock.required_features( i );
bool supported = false;
if ( feature == "OsmSchema-V0.6" )
supported = true;
else if ( feature == "DenseNodes" )
supported = true;
if ( !supported ) {
std::cerr << "[error] required feature not supported: " << feature.data() << std::endl;
return false;
}
}
} else {
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
void ReadData() {
bool keepRunning = true;
do {
_ThreadData *threadData = new _ThreadData();
keepRunning = readNextBlock(input, threadData);
if (keepRunning)
threadDataQueue->push(threadData);
else
threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered
} while(keepRunning);
}
void ParseData() {
while (1) {
_ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData);
if (threadData == NULL) {
cout << "Parse Data Thread Finished" << endl;
threadDataQueue->push(NULL); // Signal end of data for other threads
break;
}
loadBlock(threadData);
for(int i = 0; i < threadData->PBFprimitiveBlock.primitivegroup_size(); i++) {
threadData->currentGroupID = i;
loadGroup(threadData);
if(threadData->entityTypeIndicator == TypeNode)
parseNode(threadData);
if(threadData->entityTypeIndicator == TypeWay)
parseWay(threadData);
if(threadData->entityTypeIndicator == TypeRelation)
parseRelation(threadData);
if(threadData->entityTypeIndicator == TypeDenseNode)
parseDenseNode(threadData);
}
delete threadData;
threadData = NULL;
}
}
bool Parse() {
// Start the read and parse threads
boost::thread readThread(boost::bind(&PBFParser::ReadData, this));
boost::thread parseThread(boost::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
readThread.join();
parseThread.join();
return true;
}
private:
void parseDenseNode(_ThreadData * threadData) {
const OSMPBF::DenseNodes& dense = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).dense();
int denseTagIndex = 0;
int m_lastDenseID = 0;
int m_lastDenseLatitude = 0;
int m_lastDenseLongitude = 0;
for(int i = 0; i < dense.id_size(); i++) {
HashTable<std::string, std::string> keyVals;
m_lastDenseID += dense.id( i );
m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i );
_Node n;
n.id = m_lastDenseID;
n.lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() +threadData-> PBFprimitiveBlock.lat_offset() ) / NANO;
n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) {
int tagValue = dense.keys_vals( denseTagIndex );
if(tagValue == 0) {
denseTagIndex++;
break;
}
int keyValue = dense.keys_vals ( denseTagIndex+1 );
std::string key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
std::string value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
keyVals.Add(key, value);
denseTagIndex += 2;
}
if(!(*addressCallback)(n, keyVals))
std::cerr << "[PBFParser] adress not parsed" << std::endl;
if(!(*nodeCallback)(n))
std::cerr << "[PBFParser] dense node not parsed" << std::endl;
}
}
void parseNode(_ThreadData * threadData) {
_Node n;
if(!(*nodeCallback)(n))
std::cerr << "[PBFParser] simple node not parsed" << std::endl;
}
void parseRelation(_ThreadData * threadData) {
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); i++ ) {
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
for(int k = 0; k < inputRelation.keys_size(); k++) {
const std::string key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key && "restriction" == val) {
isRestriction = true;
}
if ("restriction" == key) {
if(val.find("only_") == 0)
isOnlyRestriction = true;
}
}
if(isRestriction) {
long long lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); rolesIndex++) {
string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) {
continue;
}
switch(inputRelation.types(rolesIndex)) {
case 0: //node
if("from" == role || "to" == role) //Only via should be a node
continue;
assert("via" == role);
if(UINT_MAX != currentRestrictionContainer.viaWay)
currentRestrictionContainer.viaWay = UINT_MAX;
assert(UINT_MAX == currentRestrictionContainer.viaWay);
currentRestrictionContainer.restriction.viaNode = lastRef;
break;
case 1: //way
assert("from" == role || "to" == role || "via" == role);
if("from" == role) {
currentRestrictionContainer.fromWay = lastRef;
}
if ("to" == role) {
currentRestrictionContainer.toWay = lastRef;
}
if ("via" == role) {
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
currentRestrictionContainer.viaWay = lastRef;
}
break;
case 2: //relation, not used. relations relating to relations are evil.
continue;
assert(false);
break;
default: //should not happen
cout << "unknown";
assert(false);
break;
}
}
// if(UINT_MAX != currentRestriction.viaNode) {
// cout << "restr from " << currentRestriction.from << " via ";
// cout << "node " << currentRestriction.viaNode;
// cout << " to " << currentRestriction.to << endl;
// }
if(!(*restrictionCallback)(currentRestrictionContainer))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
void parseWay(_ThreadData * threadData) {
if( threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size() > 0) {
for(int i = 0; i < threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i++) {
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
_Way w;
w.id = inputWay.id();
unsigned pathNode(0);
for(int i = 0; i < inputWay.refs_size(); i++) {
pathNode += inputWay.refs(i);
w.path.push_back(pathNode);
}
assert(inputWay.keys_size() == inputWay.vals_size());
for(int i = 0; i < inputWay.keys_size(); i++) {
const std::string key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(i));
const std::string val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(i));
w.keyVals.Add(key, val);
}
if(!(*wayCallback)(w)) {
std::cerr << "[PBFParser] way not parsed" << std::endl;
}
}
}
}
void loadGroup(_ThreadData * threadData) {
groupCount++;
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = 0;
if ( group.nodes_size() != 0 ) {
threadData->entityTypeIndicator = TypeNode;
}
if ( group.ways_size() != 0 ) {
threadData->entityTypeIndicator = TypeWay;
}
if ( group.relations_size() != 0 ) {
threadData->entityTypeIndicator = TypeRelation;
}
if ( group.has_dense() ) {
threadData->entityTypeIndicator = TypeDenseNode;
assert( group.dense().id_size() != 0 );
}
assert( threadData->entityTypeIndicator != 0 );
}
void loadBlock(_ThreadData * threadData) {
blockCount++;
threadData->currentGroupID = 0;
threadData->currentEntityID = 0;
}
/* Reverses Network Byte Order into something usable */
inline unsigned swapEndian(unsigned x) {
if(getMachineEndianness() == LittleEndian)
return ( (x>>24) | ((x<<8) & 0x00FF0000) | ((x>>8) & 0x0000FF00) | (x<<24) );
return x;
}
bool readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData) {
int size(0);
stream.read((char *)&size, sizeof(int));
size = swapEndian(size);
if(stream.eof()) {
return false;
}
if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) {
return false;
}
char *data = (char*)malloc(size);
stream.read(data, size*sizeof(data[0]));
if ( !(threadData->PBFBlobHeader).ParseFromArray( data, size ) ){
free(data);
return false;
}
free(data);
return true;
}
bool unpackZLIB(std::fstream & stream, _ThreadData * threadData) {
unsigned rawSize = threadData->PBFBlob.raw_size();
char* unpackedDataArray = (char*)malloc(rawSize);
z_stream compressedDataStream;
compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data();
compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size();
compressedDataStream.next_out = ( unsigned char* ) unpackedDataArray;
compressedDataStream.avail_out = rawSize;
compressedDataStream.zalloc = Z_NULL;
compressedDataStream.zfree = Z_NULL;
compressedDataStream.opaque = Z_NULL;
int ret = inflateInit( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to init zlib stream" << std::endl;
free(unpackedDataArray);
return false;
}
ret = inflate( &compressedDataStream, Z_FINISH );
if ( ret != Z_STREAM_END ) {
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << ret << std::endl;
free(unpackedDataArray);
return false;
}
ret = inflateEnd( &compressedDataStream );
if ( ret != Z_OK ) {
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
free(unpackedDataArray);
return false;
}
threadData->charBuffer.clear(); threadData->charBuffer.resize(rawSize);
for(unsigned i = 0; i < rawSize; i++) {
threadData->charBuffer[i] = unpackedDataArray[i];
}
free(unpackedDataArray);
return true;
}
bool unpackLZMA(std::fstream & stream, _ThreadData * threadData) {
return false;
}
bool readBlob(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof())
return false;
int size = threadData->PBFBlobHeader.datasize();
if ( size < 0 || size > MAX_BLOB_SIZE ) {
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char* data = (char*)malloc(size);
stream.read(data, sizeof(data[0])*size);
if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) {
std::cerr << "[error] failed to parse blob" << std::endl;
free(data);
return false;
}
if ( threadData->PBFBlob.has_raw() ) {
const std::string& data = threadData->PBFBlob.raw();
threadData->charBuffer.clear();
threadData->charBuffer.resize( data.size() );
for ( unsigned i = 0; i < data.size(); i++ ) {
threadData->charBuffer[i] = data[i];
}
} else if ( threadData->PBFBlob.has_zlib_data() ) {
if ( !unpackZLIB(stream, threadData) ) {
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
free(data);
return false;
}
} else if ( threadData->PBFBlob.has_lzma_data() ) {
if ( !unpackLZMA(stream, threadData) )
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
free(data);
return false;
} else {
std::cerr << "[error] Blob contains no data" << std::endl;
free(data);
return false;
}
free(data);
return true;
}
bool readNextBlock(std::fstream& stream, _ThreadData * threadData) {
if(stream.eof()) {
return false;
}
if ( !readPBFBlobHeader(stream, threadData) )
return false;
if ( threadData->PBFBlobHeader.type() != "OSMData" ) {
std::cerr << "[error] invalid block type, found" << threadData->PBFBlobHeader.type().data() << "instead of OSMData" << std::endl;
return false;
}
if ( !readBlob(stream, threadData) )
return false;
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
std::cerr << "[error] failed to parse PrimitiveBlock" << std::endl;
return false;
}
return true;
}
static Endianness getMachineEndianness() {
int i(1);
char *p = (char *) &i;
if (p[0] == 1)
return LittleEndian;
return BigEndian;
}
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
/* counting the number of read blocks and groups */
unsigned groupCount;
unsigned blockCount;
/* Function pointer for nodes */
bool (*nodeCallback)(_Node);
bool (*wayCallback)(_Way);
bool (*restrictionCallback)(_RawRestrictionContainer);
bool (*addressCallback)(_Node, HashTable<std::string, std::string>);
/* the input stream to parse */
std::fstream input;
/* ThreadData Queue */
ConcurrentQueue < _ThreadData* >* threadDataQueue;
};
#endif /* PBFPARSER_H_ */
-90
View File
@@ -1,90 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef PERCENT_H
#define PERCENT_H
#include <iostream>
#ifdef _OPENMP
#include <omp.h>
#endif
class Percent
{
public:
/**
* Constructor.
* @param maxValue the value that corresponds to 100%
* @param step the progress is shown in steps of 'step' percent
*/
Percent(unsigned maxValue, unsigned step = 5) {
reinit(maxValue, step);
}
/** Reinitializes this object. */
void reinit(unsigned maxValue, unsigned step = 5) {
_maxValue = maxValue;
_current_value = 0;
_intervalPercent = _maxValue / 100;
_nextThreshold = _intervalPercent;
_lastPercent = 0;
_step = step;
}
/** If there has been significant progress, display it. */
void printStatus(unsigned currentValue) {
if (currentValue >= _nextThreshold) {
_nextThreshold += _intervalPercent;
printPercent( currentValue / (double)_maxValue * 100 );
}
if (currentValue + 1 == _maxValue)
std::cout << " 100%" << std::endl;
}
void printIncrement()
{
#pragma omp atomic
_current_value++;
printStatus(_current_value);
}
private:
unsigned _current_value;
unsigned _maxValue;
unsigned _intervalPercent;
unsigned _nextThreshold;
unsigned _lastPercent;
unsigned _step;
/** Displays the new progress. */
void printPercent(double percent) {
while (percent >= _lastPercent+_step) {
_lastPercent+=_step;
if (_lastPercent % 10 == 0) {
std::cout << " " << _lastPercent << "% ";
}
else {
std::cout << ".";
}
std::cout.flush();
}
}
};
#endif // PERCENT_H
-76
View File
@@ -1,76 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef PHANTOMNODES_H_
#define PHANTOMNODES_H_
#include "ExtractorStructs.h"
struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX) {}
NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID;
int weight1;
int weight2;
_Coordinate location;
void Reset() {
edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX;
weight1 = INT_MAX;
weight2 = INT_MAX;
location.Reset();
}
bool isBidirected() const {
return weight2 != INT_MAX;
}
};
struct PhantomNodes {
PhantomNode startPhantom;
PhantomNode targetPhantom;
void Reset() {
startPhantom.Reset();
targetPhantom.Reset();
}
bool PhantomsAreOnSameNodeBasedEdge() const {
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
}
bool AtLeastOnePhantomNodeIsUINTMAX() const {
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX);
}
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
out << "startCoord: " << pn.startPhantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
return out;
}
struct NodesOfEdge {
NodeID edgeBasedNode;
double ratio;
_Coordinate projectedPoint;
};
#endif /* PHANTOMNODES_H_ */
-267
View File
@@ -1,267 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef SEARCHENGINE_H_
#define SEARCHENGINE_H_
#include <climits>
#include <deque>
#include <boost/thread.hpp>
#include "BinaryHeap.h"
#include "PhantomNodes.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
struct _HeapData {
NodeID parent;
_HeapData( NodeID p ) : parent(p) { }
};
typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr;
template<class EdgeData, class GraphT>
class SearchEngine {
private:
const GraphT * _graph;
NodeInformationHelpDesk * nodeHelpDesk;
std::vector<string> * _names;
static HeapPtr _forwardHeap;
static HeapPtr _backwardHeap;
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
public:
SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, std::vector<string> * n = new std::vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
~SearchEngine() {}
inline const void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
result.lat = nodeHelpDesk->getLatitudeOfNode(id);
result.lon = nodeHelpDesk->getLongitudeOfNode(id);
}
inline void InitializeThreadLocalStorageIfNecessary() {
if(!_forwardHeap.get())
_forwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
else
_forwardHeap->Clear();
if(!_backwardHeap.get())
_backwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
else
_backwardHeap->Clear();
}
int ComputeRoute(PhantomNodes & phantomNodes, std::vector<_PathData> & path) {
int _upperbound = INT_MAX;
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
return _upperbound;
InitializeThreadLocalStorageIfNecessary();
NodeID middle = ( NodeID ) UINT_MAX;
bool stOnSameEdge = false;
//Handling the special case that origin and destination are on same edge and that the order is correct.
if(phantomNodes.PhantomsAreOnSameNodeBasedEdge()){
if(phantomNodes.startPhantom.isBidirected() && phantomNodes.targetPhantom.isBidirected()) {
int weight = std::abs(phantomNodes.startPhantom.weight1 - phantomNodes.targetPhantom.weight1);
return weight;
} else if(phantomNodes.startPhantom.weight1 <= phantomNodes.targetPhantom.weight1){
int weight = std::abs(phantomNodes.startPhantom.weight1 - phantomNodes.targetPhantom.weight1);
return weight;
} else {
stOnSameEdge = true;
}
}
//insert start and/or target node of start edge
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, -phantomNodes.startPhantom.weight1, phantomNodes.startPhantom.edgeBasedNode);
if(phantomNodes.startPhantom.isBidirected() ) {
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, -phantomNodes.startPhantom.weight2, phantomNodes.startPhantom.edgeBasedNode+1);
}
//insert start and/or target node of target edge id
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, -phantomNodes.targetPhantom.weight1, phantomNodes.targetPhantom.edgeBasedNode);
if(phantomNodes.targetPhantom.isBidirected() ) {
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, -phantomNodes.targetPhantom.weight2, phantomNodes.targetPhantom.edgeBasedNode+1);
}
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
if(_forwardHeap->Size() > 0){
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound, stOnSameEdge);
}
if(_backwardHeap->Size() > 0){
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound, stOnSameEdge);
}
}
if ( _upperbound == INT_MAX ) {
return _upperbound;
}
NodeID pathNode = middle;
deque<NodeID> packedPath;
while(phantomNodes.startPhantom.edgeBasedNode != pathNode && (!phantomNodes.startPhantom.isBidirected() || phantomNodes.startPhantom.edgeBasedNode+1 != pathNode) ) {
pathNode = _forwardHeap->GetData(pathNode).parent;
packedPath.push_front(pathNode);
}
packedPath.push_back(middle);
pathNode = middle;
while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected() || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) {
pathNode = _backwardHeap->GetData(pathNode).parent;
packedPath.push_back(pathNode);
}
for(deque<NodeID>::size_type i = 0;i < packedPath.size() - 1;i++){
_UnpackEdge(packedPath[i], packedPath[i + 1], path);
}
return _upperbound;
}
inline bool FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) const {
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
return true;
}
inline bool FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result) const {
return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
}
inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
if(s == t)
return 0;
EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _graph->FindEdge( t, s );
if(UINT_MAX == e) {
return 0;
}
assert(e != UINT_MAX);
const EdgeData ed = _graph->GetEdgeData(e);
return ed.via;
}
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
return ((nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)));
}
inline std::string GetEscapedNameForEdgeBasedEdgeID(const unsigned edgeID) const {
const unsigned nameID = _graph->GetEdgeData(edgeID).nameID1;
return GetEscapedNameForNameID(nameID);
}
private:
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, int *_upperbound, const bool stOnSameEdge) const {
const NodeID node = _forwardHeap->DeleteMin();
const int distance = _forwardHeap->GetKey(node);
if(_backwardHeap->WasInserted(node) && (!stOnSameEdge || distance > 0) ){
const int newDistance = _backwardHeap->GetKey(node) + distance;
if(newDistance < *_upperbound){
*middle = node;
*_upperbound = newDistance;
}
}
if(distance > *_upperbound){
_forwardHeap->DeleteAll();
return;
}
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
const EdgeData & data = _graph->GetEdgeData(edge);
bool backwardDirectionFlag = (!forwardDirection) ? data.forward : data.backward;
if(backwardDirectionFlag) {
const NodeID to = _graph->GetTarget(edge);
const int edgeWeight = data.distance;
assert( edgeWeight > 0 );
//Stalling
if(_forwardHeap->WasInserted( to )) {
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
return;
}
}
}
}
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
const EdgeData & data = _graph->GetEdgeData(edge);
bool forwardDirectionFlag = (forwardDirection ? data.forward : data.backward );
if(forwardDirectionFlag) {
const NodeID to = _graph->GetTarget(edge);
const int edgeWeight = data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
//New Node discovered -> Add to Heap + Node Info Storage
if ( !_forwardHeap->WasInserted( to ) ) {
_forwardHeap->Insert( to, toDistance, node );
}
//Found a shorter Path -> Update distance
else if ( toDistance < _forwardHeap->GetKey( to ) ) {
_forwardHeap->GetData( to ).parent = node;
_forwardHeap->DecreaseKey( to, toDistance );
//new parent
}
}
}
}
inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) const {
assert(source != target);
//find edge first.
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
int smallestWeight = INT_MAX;
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source);eit < _graph->EndEdges(source);eit++){
const int weight = _graph->GetEdgeData(eit).distance;
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward){
smallestEdge = eit;
smallestWeight = weight;
}
}
if(smallestEdge == SPECIAL_EDGEID){
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target);eit < _graph->EndEdges(target);eit++){
const int weight = _graph->GetEdgeData(eit).distance;
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward){
smallestEdge = eit;
smallestWeight = weight;
}
}
}
assert(smallestWeight != INT_MAX);
const EdgeData& ed = _graph->GetEdgeData(smallestEdge);
if(ed.shortcut) {//unpack
const NodeID middle = ed.via;
_UnpackEdge(source, middle, path);
_UnpackEdge(middle, target, path);
return false;
} else {
assert(!ed.shortcut);
path.push_back(_PathData(ed.via, ed.nameID1, ed.turnInstruction, ed.distance) );
return true;
}
}
};
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_forwardHeap;
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_backwardHeap;
#endif /* SEARCHENGINE_H_ */
-39
View File
@@ -1,39 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_
#include <climits>
struct SegmentInformation {
_Coordinate location;
NodeID nameID;
unsigned length;
unsigned duration;
short turnInstruction;
bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const unsigned len, const unsigned dur, const short tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), turnInstruction(tInstr), necessary(nec) {}
SegmentInformation(const _Coordinate & loc, const NodeID nam, const unsigned len, const unsigned dur, const short tInstr) :
location(loc), nameID(nam), length(len), duration(dur), turnInstruction(tInstr), necessary(tInstr != 0) {}
};
#endif /* SEGMENTINFORMATION_H_ */
-162
View File
@@ -1,162 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED
#include <vector>
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#include "../typedefs.h"
#include "ImportEdge.h"
template< typename EdgeDataT>
class StaticGraph {
public:
typedef NodeID NodeIterator;
typedef NodeID EdgeIterator;
typedef EdgeDataT EdgeData;
class InputEdge {
public:
EdgeDataT data;
NodeIterator source;
NodeIterator target;
bool operator<( const InputEdge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
};
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( graph.begin(), graph.end() );
#else
std::sort( graph.begin(), graph.end() );
#endif
_numNodes = nodes;
_numEdges = ( EdgeIterator ) graph.size();
_nodes.resize( _numNodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for ( NodeIterator node = 0; node <= _numNodes; ++node ) {
EdgeIterator lastEdge = edge;
while ( edge < _numEdges && graph[edge].source == node )
++edge;
_nodes[node].firstEdge = position; //=edge
position += edge - lastEdge; //remove
}
_edges.resize( position ); //(edge)
edge = 0;
for ( NodeIterator node = 0; node < _numNodes; ++node ) {
for ( EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {
_edges[i].target = graph[edge].target;
_edges[i].data = graph[edge].data;
assert(_edges[i].data.distance > 0);
edge++;
}
}
}
unsigned GetNumberOfNodes() const {
return _numNodes;
}
unsigned GetNumberOfEdges() const {
return _numEdges;
}
unsigned GetOutDegree( const NodeIterator &n ) const {
return BeginEdges(n)-EndEdges(n) - 1;
}
inline NodeIterator GetTarget( const EdgeIterator &e ) const {
return NodeIterator( _edges[e].target );
}
inline EdgeDataT &GetEdgeData( const EdgeIterator &e ) {
return _edges[e].data;
}
const EdgeDataT &GetEdgeData( const EdgeIterator &e ) const {
return _edges[e].data;
}
EdgeIterator BeginEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n].firstEdge );
}
EdgeIterator EndEdges( const NodeIterator &n ) const {
return EdgeIterator( _nodes[n+1].firstEdge );
}
//searches for a specific edge
EdgeIterator FindEdge( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator smallestEdge = SPECIAL_EDGEID;
EdgeWeight smallestWeight = UINT_MAX;
for ( EdgeIterator edge = BeginEdges( from ); edge < EndEdges(from); edge++ ) {
const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance;
if(target == to && weight < smallestWeight) {
smallestEdge = edge; smallestWeight = weight;
}
}
return smallestEdge;
}
EdgeIterator FindEdgeInEitherDirection( const NodeIterator &from, const NodeIterator &to ) const {
EdgeIterator tmp = FindEdge( from, to );
return (UINT_MAX != tmp ? tmp : FindEdge( to, from ));
}
EdgeIterator FindEdgeIndicateIfReverse( const NodeIterator &from, const NodeIterator &to, bool & result ) const {
EdgeIterator tmp = FindEdge( from, to );
if(UINT_MAX == tmp) {
tmp = FindEdge( to, from );
if(UINT_MAX != tmp)
result = true;
}
return tmp;
}
private:
struct _StrNode {
//index of the first edge
EdgeIterator firstEdge;
};
struct _StrEdge {
NodeID target;
EdgeDataT data;
};
NodeIterator _numNodes;
EdgeIterator _numEdges;
std::vector< _StrNode > _nodes;
std::vector< _StrEdge > _edges;
};
#endif // STATICGRAPH_H_INCLUDED
-230
View File
@@ -1,230 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
KD Tree coded by Christian Vetter, Monav Project
*/
#ifndef STATICKDTREE_H_INCLUDED
#define STATICKDTREE_H_INCLUDED
#include <vector>
#ifdef _GLIBCXX_PARALLEL
#include <parallel/algorithm>
#else
#include <algorithm>
#endif
#include <stack>
#include <limits>
namespace KDTree {
#define KDTREE_BASESIZE (8)
template< unsigned k, typename T >
class BoundingBox {
public:
BoundingBox() {
for ( unsigned dim = 0; dim < k; ++dim ) {
min[dim] = std::numeric_limits< T >::min();
max[dim] = std::numeric_limits< T >::max();
}
}
T min[k];
T max[k];
};
struct NoData {};
template< unsigned k, typename T >
class EuclidianMetric {
public:
double operator() ( const T left[k], const T right[k] ) {
double result = 0;
for ( unsigned i = 0; i < k; ++i ) {
double temp = (double)left[i] - (double)right[i];
result += temp * temp;
}
return result;
}
double operator() ( const BoundingBox< k, T > &box, const T point[k] ) {
T nearest[k];
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( point[dim] < box.min[dim] )
nearest[dim] = box.min[dim];
else if ( point[dim] > box.max[dim] )
nearest[dim] = box.max[dim];
else
nearest[dim] = point[dim];
}
return operator() ( point, nearest );
}
};
template < unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric< k, T > >
class StaticKDTree {
public:
struct InputPoint {
T coordinates[k];
Data data;
bool operator==( const InputPoint& right )
{
for ( int i = 0; i < k; i++ ) {
if ( coordinates[i] != right.coordinates[i] )
return false;
}
return true;
}
};
StaticKDTree( std::vector< InputPoint > * points ){
assert( k > 0 );
assert ( points->size() > 0 );
size = points->size();
kdtree = new InputPoint[size];
for ( Iterator i = 0; i != size; ++i ) {
kdtree[i] = points->at(i);
for ( unsigned dim = 0; dim < k; ++dim ) {
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] )
boundingBox.min[dim] = kdtree[i].coordinates[dim];
if ( kdtree[i].coordinates[dim] > boundingBox.max[dim] )
boundingBox.max[dim] = kdtree[i].coordinates[dim];
}
}
std::stack< Tree > s;
s.push ( Tree ( 0, size, 0 ) );
while ( !s.empty() ) {
Tree tree = s.top();
s.pop();
if ( tree.right - tree.left < KDTREE_BASESIZE )
continue;
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
#ifdef _GLIBCXX_PARALLEL
__gnu_parallel::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
#else
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
#endif
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) );
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) );
}
}
~StaticKDTree(){
delete[] kdtree;
}
bool NearestNeighbor( InputPoint* result, const InputPoint& point ) {
Metric distance;
bool found = false;
double nearestDistance = std::numeric_limits< T >::max();
std::stack< NNTree > s;
s.push ( NNTree ( 0, size, 0, boundingBox ) );
while ( !s.empty() ) {
NNTree tree = s.top();
s.pop();
if ( distance( tree.box, point.coordinates ) >= nearestDistance )
continue;
if ( tree.right - tree.left < KDTREE_BASESIZE ) {
for ( unsigned i = tree.left; i < tree.right; i++ ) {
double newDistance = distance( kdtree[i].coordinates, point.coordinates );
if ( newDistance < nearestDistance ) {
nearestDistance = newDistance;
*result = kdtree[i];
found = true;
}
}
continue;
}
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
double newDistance = distance( kdtree[middle].coordinates, point.coordinates );
if ( newDistance < nearestDistance ) {
nearestDistance = newDistance;
*result = kdtree[middle];
found = true;
}
Less comperator( tree.dimension );
if ( !comperator( point, kdtree[middle] ) ) {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( second );
s.push( first );
}
else {
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
s.push( first );
s.push( second );
}
}
return found;
}
private:
typedef unsigned Iterator;
struct Tree {
Iterator left;
Iterator right;
unsigned dimension;
Tree() {}
Tree( Iterator l, Iterator r, unsigned d ): left( l ), right( r ), dimension( d ) {}
};
struct NNTree {
Iterator left;
Iterator right;
unsigned dimension;
BoundingBox< k, T > box;
NNTree() {}
NNTree( Iterator l, Iterator r, unsigned d, const BoundingBox< k, T >& b ): left( l ), right( r ), dimension( d ), box ( b ) {}
};
class Less {
public:
Less( unsigned d ) {
dimension = d;
assert( dimension < k );
}
bool operator() ( const InputPoint& left, const InputPoint& right ) {
assert( dimension < k );
return left.coordinates[dimension] < right.coordinates[dimension];
}
private:
unsigned dimension;
};
BoundingBox< k, T > boundingBox;
InputPoint* kdtree;
Iterator size;
};
}
#endif // STATICKDTREE_H_INCLUDED
-154
View File
@@ -1,154 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef TURNINSTRUCTIONS_H_
#define TURNINSTRUCTIONS_H_
#include <string>
//This is a hack until c++0x is available enough to use scoped enums
struct TurnInstructionsClass {
const static short NoTurn = 0; //Give no instruction at all
const static short GoStraight = 1; //Tell user to go straight!
const static short TurnSlightRight = 2;
const static short TurnRight = 3;
const static short TurnSharpRight = 4;
const static short UTurn = 5;
const static short TurnSharpLeft = 6;
const static short TurnLeft = 7;
const static short TurnSlightLeft = 8;
const static short ReachViaPoint = 9;
const static short HeadOn = 10;
const static short EnterRoundAbout = 11;
const static short LeaveRoundAbout = 12;
const static short StayOnRoundAbout = 13;
std::string TurnStrings[14];
std::string Ordinals[11];
//This is a hack until c++0x is available enough to use initializer lists.
TurnInstructionsClass(){
TurnStrings [0] = "";
TurnStrings [1] = "Continue";
TurnStrings [2] = "Turn slight right";
TurnStrings [3] = "Turn right";
TurnStrings [4] = "Turn sharp right";
TurnStrings [5] = "U-Turn";
TurnStrings [6] = "Turn sharp left";
TurnStrings [7] = "Turn left";
TurnStrings [8] = "Turn slight left";
TurnStrings [9] = "Reach via point";
TurnStrings[10] = "Head";
TurnStrings[11] = "Enter round-about";
TurnStrings[12] = "Leave round-about";
TurnStrings[13] = "Stay on round-about";
Ordinals[0] = "zeroth";
Ordinals[1] = "first";
Ordinals[2] = "second";
Ordinals[3] = "third";
Ordinals[4] = "fourth";
Ordinals[5] = "fifth";
Ordinals[6] = "sixth";
Ordinals[7] = "seventh";
Ordinals[8] = "eighth";
Ordinals[9] = "nineth";
Ordinals[10] = "tenth";
};
static inline double GetTurnDirectionOfInstruction( const double angle ) {
if(angle >= 23 && angle < 67) {
return TurnSharpRight;
}
if (angle >= 67 && angle < 113) {
return TurnRight;
}
if (angle >= 113 && angle < 158) {
return TurnSlightRight;
}
if (angle >= 158 && angle < 202) {
return GoStraight;
}
if (angle >= 202 && angle < 248) {
return TurnSlightLeft;
}
if (angle >= 248 && angle < 292) {
return TurnLeft;
}
if (angle >= 292 && angle < 336) {
return TurnSharpLeft;
}
return 5;
}
static inline bool TurnIsNecessary ( const short turnInstruction ) {
if(NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
return false;
return true;
}
// static inline void getDirectionOfInstruction(double angle, DirectionOfInstruction & dirInst) {
// if(angle >= 23 && angle < 67) {
// dirInst.direction = "southeast";
// dirInst.shortDirection = "SE";
// return;
// }
// if(angle >= 67 && angle < 113) {
// dirInst.direction = "south";
// dirInst.shortDirection = "S";
// return;
// }
// if(angle >= 113 && angle < 158) {
// dirInst.direction = "southwest";
// dirInst.shortDirection = "SW";
// return;
// }
// if(angle >= 158 && angle < 202) {
// dirInst.direction = "west";
// dirInst.shortDirection = "W";
// return;
// }
// if(angle >= 202 && angle < 248) {
// dirInst.direction = "northwest";
// dirInst.shortDirection = "NW";
// return;
// }
// if(angle >= 248 && angle < 292) {
// dirInst.direction = "north";
// dirInst.shortDirection = "N";
// return;
// }
// if(angle >= 292 && angle < 336) {
// dirInst.direction = "northeast";
// dirInst.shortDirection = "NE";
// return;
// }
// dirInst.direction = "East";
// dirInst.shortDirection = "E";
// return;
// }
//
};
static TurnInstructionsClass TurnInstructions;
#endif /* TURNINSTRUCTIONS_H_ */
-70
View File
@@ -1,70 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef TIMEUTIL_H_
#define TIMEUTIL_H_
#include <climits>
#include <cmath>
#include <cstdlib>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef _WIN32
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock.h>
void gettimeofday(struct timeval* t,void* timezone)
{ struct _timeb timebuffer;
_ftime( &timebuffer );
t->tv_sec=timebuffer.time;
t->tv_usec=1000*timebuffer.millitm;
}
#else
#include <sys/time.h>
#endif
#ifdef _WIN32
#include <boost/functional/hash.hpp>
#else
#include <tr1/functional_hash.h>
#endif
#include <boost/thread.hpp>
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
static inline double y2lat(double a) { return 180/M_PI * (2 * atan(exp(a*M_PI/180)) - M_PI/2); }
static inline double lat2y(double a) { return 180/M_PI * log(tan(M_PI/4+a*(M_PI/180)/2)); }
static inline unsigned boost_thread_id_hash(boost::thread::id const& id) {
std::stringstream ostr;
ostr << id;
std::tr1::hash<std::string> h;
return h(ostr.str());
}
#endif /* TIMEUTIL_H_ */
-217
View File
@@ -1,217 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef XMLPARSER_H_
#define XMLPARSER_H_
#include <libxml/xmlreader.h>
#include "../typedefs.h"
#include "BaseParser.h"
#include "HashTable.h"
#include "ExtractorStructs.h"
#include "InputReaderFactory.h"
class XMLParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
public:
XMLParser(const char * filename) {
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
inputReader = inputReaderFactory(filename);
}
virtual ~XMLParser() {}
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*restrictionCallbackPointer)(_RawRestrictionContainer), bool (*wayCallbackPointer)(_Way), bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
nodeCallback = *nodeCallbackPointer;
wayCallback = *wayCallbackPointer;
restrictionCallback = *restrictionCallbackPointer;
return true;
}
bool Init() {
return (xmlTextReaderRead( inputReader ) == 1);
}
bool Parse() {
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int type = xmlTextReaderNodeType( inputReader );
//1 is Element
if ( type != 1 )
continue;
xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL )
continue;
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
_Node n = _ReadXMLNode( );
if(!(*nodeCallback)(n))
std::cerr << "[XMLParser] node not parsed" << std::endl;
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) {
string name;
_Way way = _ReadXMLWay( );
if(!(*wayCallback)(way)) {
std::cerr << "[XMLParser] way not parsed" << std::endl;
}
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
_Relation r;
r.type = _Relation::unknown;
//todo: parse relation
}
xmlFree( currentName );
}
return true;
}
private:
_Relation _ReadXMLRelation ( ) {
_Relation relation;
relation.type = _Relation::unknown;
return relation;
}
_Way _ReadXMLWay( ) {
_Way way;
way.direction = _Way::notSure;
way.speed = -1;
way.type = -1;
way.useful = false;
way.access = true;
// cout << "new way" << endl;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
// cout << "->k=" << k << ", v=" << value << endl;
if ( k != NULL && value != NULL ) {
way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value));
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) {
way.path.push_back( atoi(( const char* ) ref ) );
xmlFree( ref );
}
}
xmlFree( childName );
}
}
return way;
}
_Node _ReadXMLNode( ) {
_Node node;
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
xmlFree( attribute );
}
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
if ( attribute != NULL ) {
node.id = atoi(( const char* ) attribute );
xmlFree( attribute );
}
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );
while ( xmlTextReaderRead( inputReader ) == 1 ) {
const int childType = xmlTextReaderNodeType( inputReader );
// 1 = Element, 15 = EndElement
if ( childType != 1 && childType != 15 )
continue;
const int childDepth = xmlTextReaderDepth( inputReader );
xmlChar* childName = xmlTextReaderName( inputReader );
if ( childName == NULL )
continue;
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) {
xmlFree( childName );
break;
}
if ( childType != 1 ) {
xmlFree( childName );
continue;
}
if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) {
xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" );
xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" );
if ( k != NULL && value != NULL ) {
if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) {
if ( xmlStrEqual( value, ( const xmlChar* ) "traffic_signals" ) == 1 ){
//node.trafficSignal = true;
}
}
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
xmlFree( value );
}
xmlFree( childName );
}
}
return node;
}
/* Input Reader */
xmlTextReaderPtr inputReader;
/* Function pointer for nodes */
bool (*nodeCallback)(_Node);
bool (*wayCallback)(_Way);
bool (*restrictionCallback)(_RawRestrictionContainer);
};
#endif /* XMLPARSER_H_ */
-53
View File
@@ -1,53 +0,0 @@
/** Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
option java_package = "crosby.binary";
package OSMPBF;
//protoc --java_out=../.. fileformat.proto
//
// STORAGE LAYER: Storing primitives.
//
message Blob {
optional bytes raw = 1; // No compression
optional int32 raw_size = 2; // When compressed, the uncompressed size
// Possible compressed versions of the data.
optional bytes zlib_data = 3;
// PROPOSED feature for LZMA compressed data. SUPPORT IS NOT REQUIRED.
optional bytes lzma_data = 4;
// Formerly used for bzip2 compressed data. Depreciated in 2010.
optional bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number.
}
/* A file contains an sequence of fileblock headers, each prefixed by
their length in network byte order, followed by a data block
containing the actual data. types staring with a "_" are reserved.
*/
message BlobHeader {
required string type = 1;
optional bytes indexdata = 2;
required int32 datasize = 3;
}
-226
View File
@@ -1,226 +0,0 @@
/** Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
option java_package = "crosby.binary";
package OSMPBF;
/* OSM Binary file format
This is the master schema file of the OSM binary file format. This
file is designed to support limited random-access and future
extendability.
A binary OSM file consists of a sequence of FileBlocks (please see
fileformat.proto). The first fileblock contains a serialized instance
of HeaderBlock, followed by a sequence of PrimitiveBlock blocks that
contain the primitives.
Each primitiveblock is designed to be independently parsable. It
contains a string table storing all strings in that block (keys and
values in tags, roles in relations, usernames, etc.) as well as
metadata containing the precision of coordinates or timestamps in that
block.
A primitiveblock contains a sequence of primitive groups, each
containing primitives of the same type (nodes, densenodes, ways,
relations). Coordinates are stored in signed 64-bit integers. Lat&lon
are measured in units <granularity> nanodegrees. The default of
granularity of 100 nanodegrees corresponds to about 1cm on the ground,
and a full lat or lon fits into 32 bits.
Converting an integer to a lattitude or longitude uses the formula:
$OUT = IN * granularity / 10**9$. Many encoding schemes use delta
coding when representing nodes and relations.
*/
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/* Contains the file header. */
message HeaderBlock {
optional HeaderBBox bbox = 1;
/* Additional tags to aid in parsing this dataset */
repeated string required_features = 4;
repeated string optional_features = 5;
optional string writingprogram = 16;
optional string source = 17; // From the bbox field.
}
/** The bounding box field in the OSM header. BBOX, as used in the OSM
header. Units are always in nanodegrees -- they do not obey
granularity rules. */
message HeaderBBox {
required sint64 left = 1;
required sint64 right = 2;
required sint64 top = 3;
required sint64 bottom = 4;
}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
message PrimitiveBlock {
required StringTable stringtable = 1;
repeated PrimitiveGroup primitivegroup = 2;
// Granularity, units of nanodegrees, used to store coordinates in this block
optional int32 granularity = 17 [default=100];
// Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
optional int64 lat_offset = 19 [default=0];
optional int64 lon_offset = 20 [default=0];
// Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
optional int32 date_granularity = 18 [default=1000];
// Proposed extension:
//optional BBox bbox = XX;
}
// Group of OSMPrimitives. All primitives in a group must be the same type.
message PrimitiveGroup {
repeated Node nodes = 1;
optional DenseNodes dense = 2;
repeated Way ways = 3;
repeated Relation relations = 4;
repeated ChangeSet changesets = 5;
}
/** String table, contains the common strings in each block.
Note that we reserve index '0' as a delimiter, so the entry at that
index in the table is ALWAYS blank and unused.
*/
message StringTable {
repeated bytes s = 1;
}
/* Optional metadata that may be included into each primitive. */
message Info {
optional int32 version = 1 [default = -1];
optional int64 timestamp = 2;
optional int64 changeset = 3;
optional int32 uid = 4;
optional uint32 user_sid = 5; // String IDs
}
/** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */
message DenseInfo {
repeated int32 version = 1 [packed = true];
repeated sint64 timestamp = 2 [packed = true]; // DELTA coded
repeated sint64 changeset = 3 [packed = true]; // DELTA coded
repeated sint32 uid = 4 [packed = true]; // DELTA coded
repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded
}
// THIS IS STUB DESIGN FOR CHANGESETS. NOT USED RIGHT NOW.
// TODO: REMOVE THIS?
message ChangeSet {
required int64 id = 1;
//
// // Parallel arrays.
// repeated uint32 keys = 2 [packed = true]; // String IDs.
// repeated uint32 vals = 3 [packed = true]; // String IDs.
//
// optional Info info = 4;
// optional int64 created_at = 8;
// optional int64 closetime_delta = 9;
// optional bool open = 10;
// optional HeaderBBox bbox = 11;
}
message Node {
required sint64 id = 1;
// Parallel arrays.
repeated uint32 keys = 2 [packed = true]; // String IDs.
repeated uint32 vals = 3 [packed = true]; // String IDs.
optional Info info = 4; // May be omitted in omitmeta
required sint64 lat = 8;
required sint64 lon = 9;
}
/* Used to densly represent a sequence of nodes that do not have any tags.
We represent these nodes columnwise as five columns: ID's, lats, and
lons, all delta coded. When metadata is not omitted,
We encode keys & vals for all nodes as a single array of integers
containing key-stringid and val-stringid, using a stringid of 0 as a
delimiter between nodes.
( (<keyid> <valid>)* '0' )*
*/
message DenseNodes {
repeated sint64 id = 1 [packed = true]; // DELTA coded
//repeated Info info = 4;
optional DenseInfo denseinfo = 5;
repeated sint64 lat = 8 [packed = true]; // DELTA coded
repeated sint64 lon = 9 [packed = true]; // DELTA coded
// Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
repeated int32 keys_vals = 10 [packed = true];
}
message Way {
required int64 id = 1;
// Parallel arrays.
repeated uint32 keys = 2 [packed = true];
repeated uint32 vals = 3 [packed = true];
optional Info info = 4;
repeated sint64 refs = 8 [packed = true]; // DELTA coded
}
message Relation {
enum MemberType {
NODE = 0;
WAY = 1;
RELATION = 2;
}
required int64 id = 1;
// Parallel arrays.
repeated uint32 keys = 2 [packed = true];
repeated uint32 vals = 3 [packed = true];
optional Info info = 4;
// Parallel arrays
repeated int32 roles_sid = 8 [packed = true];
repeated sint64 memids = 9 [packed = true]; // DELTA encoded
repeated MemberType types = 10 [packed = true];
}
-73
View File
@@ -1,73 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../Util/StringUtil.h"
#include "../Plugins/RawRouteData.h"
struct _RouteSummary {
std::string lengthString;
std::string durationString;
std::string startName;
std::string destName;
_RouteSummary() : lengthString("0"), durationString("0"), startName("unknown street"), destName("unknown street") {}
void BuildDurationAndLengthStrings(unsigned distance, unsigned time) {
//compute distance/duration for route summary
std::ostringstream s;
s << 10*(round(distance/10.));
lengthString = s.str();
int travelTime = time/10 + 1;
s.str("");
s << travelTime;
durationString = s.str();
}
};
struct _DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(false), z(18) {}
bool instructions;
bool geometry;
bool encodeGeometry;
unsigned short z;
};
template<class SearchEngineT>
class BaseDescriptor {
public:
BaseDescriptor() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BaseDescriptor() { }
virtual void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) = 0;
virtual void SetConfig(const _DescriptorConfig & config) = 0;
};
#endif /* BASE_DESCRIPTOR_H_ */
-95
View File
@@ -1,95 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include "DescriptionFactory.h"
DescriptionFactory::DescriptionFactory() { }
DescriptionFactory::~DescriptionFactory() { }
double DescriptionFactory::GetAngleBetweenCoordinates() const {
return 0.;//GetAngleBetweenTwoEdges(previousCoordinate, currentCoordinate, nextCoordinate);
}
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) {
startPhantom = _startPhantom;
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1));
}
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom;
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
}
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) {
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) );
}
void DescriptionFactory::AppendEncodedPolylineString(std::string & output, bool isEncoded) {
if(isEncoded)
pc.printEncodedString(pathDescription, output);
else
pc.printUnencodedString(pathDescription, output);
}
void DescriptionFactory::AppendEncodedPolylineString(std::string &output) {
pc.printEncodedString(pathDescription, output);
}
void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
pc.printUnencodedString(pathDescription, output);
}
unsigned DescriptionFactory::Run(const unsigned zoomLevel) {
if(0 == pathDescription.size())
return 0;
unsigned entireLength = 0;
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistance(pathDescription[i-1].location, pathDescription[i].location);
}
unsigned lengthOfSegment = 0;
unsigned durationOfSegment = 0;
unsigned indexOfSegmentBegin = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
entireLength += pathDescription[i].length;
lengthOfSegment += pathDescription[i].length;
durationOfSegment += pathDescription[i].duration;
pathDescription[indexOfSegmentBegin].length = lengthOfSegment;
pathDescription[indexOfSegmentBegin].duration = durationOfSegment;
if(pathDescription[i].turnInstruction != 0) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID);
assert(pathDescription[i].necessary);
lengthOfSegment = 0;
durationOfSegment = 0;
indexOfSegmentBegin = i;
}
}
//Generalize poly line
dp.Run(pathDescription, zoomLevel);
//fix what needs to be fixed else
return entireLength;
}
-98
View File
@@ -1,98 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h"
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
class DescriptionFactory {
DouglasPeucker<SegmentInformation> dp;
PolylineCompressor pc;
PhantomNode startPhantom, targetPhantom;
public:
//I know, declaring this public is considered bad. I'm lazy
std::vector <SegmentInformation> pathDescription;
DescriptionFactory();
virtual ~DescriptionFactory();
double GetAngleBetweenCoordinates() const;
void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data);
void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom);
void AppendEncodedPolylineString(std::string & output, bool isEncoded);
unsigned Run(const unsigned zoomLevel);
};
#endif /* DESCRIPTIONFACTORY_H_ */
//private:
// void appendInstructionNameToString(const std::string & nameOfStreet, const std::string & instructionOrDirection, std::string &output, bool firstAdvice = false) {
// output += "[";
// if(config.instructions) {
// output += "\"";
// if(firstAdvice) {
// output += "Head ";
// }
// output += instructionOrDirection;
// output += "\",\"";
// output += nameOfStreet;
// output += "\",";
// }
// }
//
// void appendInstructionLengthToString(unsigned length, std::string &output) {
// if(config.instructions){
// std::string tmpDistance;
// intToString(10*(round(length/10.)), tmpDistance);
// output += tmpDistance;
// output += ",";
// intToString(descriptionFactory.startIndexOfGeometry, tmp);
// output += tmp;
// output += ",";
// intToString(descriptionFactory.durationOfInstruction, tmp);
// output += tmp;
// output += ",";
// output += "\"";
// output += tmpDistance;
// output += "\",";
// double angle = descriptionFactory.GetAngleBetweenCoordinates();
// DirectionOfInstruction direction;
// getDirectionOfInstruction(angle, direction);
// output += "\"";
// output += direction.shortDirection;
// output += "\",";
// std::stringstream numberString;
// numberString << fixed << setprecision(2) << angle;
// output += numberString.str();
// }
// output += "]";
// }
-67
View File
@@ -1,67 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef GPX_DESCRIPTOR_H_
#define GPX_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h"
template<class SearchEngineT>
class GPXDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
_Coordinate current;
std::string tmp;
public:
void SetConfig(const _DescriptorConfig& c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) {
reply.content += ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
reply.content += "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">";
reply.content += "<rte>";
if(distance != UINT_MAX && rawRoute.routeSegments.size()) {
convertInternalLatLonToString(phantomNodes.startPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.startPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) {
BOOST_FOREACH(_PathData pathData, rawRoute.routeSegments[segmentIdx]) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(current.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
}
}
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" ";
convertInternalLatLonToString(phantomNodes.targetPhantom.location.lon, tmp);
reply.content += "lon=\"" + tmp + "\"></rtept>";
}
reply.content += "</rte></gpx>";
}
};
#endif /* GPX_DESCRIPTOR_H_ */
-176
View File
@@ -1,176 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h"
#include "DescriptionFactory.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/StringUtil.h"
template<class SearchEngineT>
class JSONDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
_RouteSummary summary;
DescriptionFactory descriptionFactory;
std::string tmp;
_Coordinate current;
struct {
int startIndex;
int nameID;
int leaveAtExit;
} roundAbout;
public:
JSONDescriptor() {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned durationOfTrip) {
WriteHeaderToOutput(reply.content);
if(durationOfTrip != INT_MAX && rawRoute.routeSegments.size() > 0) {
summary.startName = sEngine.GetEscapedNameForNameID(phantomNodes.startPhantom.nodeBasedEdgeNameID);
descriptionFactory.SetStartSegment(phantomNodes.startPhantom);
summary.destName = sEngine.GetEscapedNameForNameID(phantomNodes.targetPhantom.nodeBasedEdgeNameID);
reply.content += "0,"
"\"status_message\": \"Found route between points\",";
for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) {
const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx];
BOOST_FOREACH(_PathData pathData, path) {
sEngine.GetCoordinatesForNodeID(pathData.node, current);
descriptionFactory.AppendSegment(current, pathData );
}
//TODO: Add via points
}
descriptionFactory.SetEndSegment(phantomNodes.targetPhantom);
} else {
//We do not need to do much, if there is no route ;-)
reply.content += "207,"
"\"status_message\": \"Cannot find route between points\",";
}
summary.BuildDurationAndLengthStrings(descriptionFactory.Run(config.z), durationOfTrip);
reply.content += "\"route_summary\": {"
"\"total_distance\":";
reply.content += summary.lengthString;
reply.content += ","
"\"total_time\":";
reply.content += summary.durationString;
reply.content += ","
"\"start_point\":\"";
reply.content += summary.startName;
reply.content += "\","
"\"end_point\":\"";
reply.content += summary.destName;
reply.content += "\"";
reply.content += "},";
reply.content += "\"route_geometry\": ";
if(config.geometry) {
if(config.encodeGeometry)
descriptionFactory.AppendEncodedPolylineString(reply.content, config.encodeGeometry);
} else {
reply.content += "[]";
}
reply.content += ","
"\"route_instructions\": [";
if(config.instructions) {
//Segment information has following format:
//["instruction","streetname",length,position,time,"length","earth_direction",azimuth]
//Example: ["Turn left","High Street",200,4,10,"200m","NE",22.5]
//See also: http://developers.cloudmade.com/wiki/navengine/JSON_format
unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmp;
//Fetch data from Factory and generate a string from it.
BOOST_FOREACH(SegmentInformation segment, descriptionFactory.pathDescription) {
if(TurnInstructions.TurnIsNecessary( segment.turnInstruction) ) {
if(TurnInstructions.EnterRoundAbout == segment.turnInstruction) {
roundAbout.nameID = segment.nameID;
roundAbout.startIndex = prefixSumOfNecessarySegments;
} else {
if(0 != prefixSumOfNecessarySegments)
reply.content += ",";
reply.content += "[\"";
if(TurnInstructions.LeaveRoundAbout == segment.turnInstruction) {
reply.content += TurnInstructions.TurnStrings[TurnInstructions.EnterRoundAbout];
reply.content += " and leave at ";
reply.content += TurnInstructions.Ordinals[roundAbout.leaveAtExit+1];
reply.content += " exit";
roundAbout.leaveAtExit = 0;
} else {
reply.content += TurnInstructions.TurnStrings[segment.turnInstruction];
}
reply.content += "\",\"";
reply.content += sEngine.GetEscapedNameForNameID(segment.nameID);
reply.content += "\",";
intToString(segment.length, tmpDist);
reply.content += tmpDist;
reply.content += ",";
intToString(prefixSumOfNecessarySegments, tmpLength);
reply.content += tmpLength;
reply.content += ",";
intToString(segment.duration, tmp);
reply.content += ",\"";
reply.content += tmpLength;
//TODO: fix heading
reply.content += "\",\"NE\",22.5";
reply.content += "]";
}
} else if(TurnInstructions.StayOnRoundAbout == segment.turnInstruction) {
++roundAbout.leaveAtExit;
}
if(segment.necessary)
++prefixSumOfNecessarySegments;
}
}
reply.content += "],";
//list all viapoints so that the client may display it
reply.content += "\"via_points\":[";
for(unsigned segmentIdx = 1; (true == config.geometry) && (segmentIdx < rawRoute.segmentEndCoordinates.size()); segmentIdx++) {
if(segmentIdx > 1)
reply.content += ",";
reply.content += "[";
if(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location.isSet())
convertInternalReversedCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, tmp);
else
convertInternalReversedCoordinateToString(rawRoute.rawViaNodeCoordinates[segmentIdx], tmp);
reply.content += tmp;
reply.content += "]";
}
reply.content += "],"
"\"transactionId\": \"OSRM Routing Engine JSON Descriptor (v0.2)\"";
reply.content += "}";
}
void WriteHeaderToOutput(std::string & output) {
output += "{"
"\"version\": 0.3,"
"\"status\":";
}
};
#endif /* JSON_DESCRIPTOR_H_ */
-9
View File
@@ -1,9 +0,0 @@
Third Party Libraries:
Scons 1.3+
Boost 1.37+
sparsehash 1.4+
stxxl 1.3.1+
libz2-dev 1.0.5+
protobuffer 2.3.0+
zlib 1.2.3.4+
-44
View File
@@ -1,44 +0,0 @@
FAQ
---
Q: What platforms does OSMR run on?
A: Virtually any Unix-like platform with g++ installed. It has been developed
under Linux and tested on MacOS X 10.6. It should run under Windows as well
though the code will need some adjustments.
Q: What is the workflow to get the engine up and running
A: Road network extraction->Preprocessing->Startup
Q: What does OSRM stand for?
A: It is an abbreviation for Open Source Routing Machine.
Q: What does HSGR stand for?
A: It is an abbreviation for Hierarchy Search GRaph.
Q: What is the .nodes file?
A: It is a map that translates between internal and external Node IDs. Remember
that external NodeIDs can be arbitrary and non-contigous. Internally the
nodes are numbered from 0 to n-1.
Q: The routing engine crashes with a seg-fault
A: Check the startup parameters.
Q: Something about the route is odd. I know that there is a better path
A: Most probably it is missing data in the OSM file.
Q: I work for this company that would like to use the code, but we are hesistant
because of the license.
A: Contact me. Probably, we can work something out.
Q: How fast is this thing?
A: Good question. Here is a number. The engine was able to handle more than
2800 requests per Minute on the German road network with the travel time
metric on a Core 2 Duo. This also includes transfer of data across a
switched 100MBit/s LAN. So, I guess it's fair to say it's fast.
Q: What is the difference between extractNetwork and extractLargeNetwork?
A: extractNetwork does all of its magic in RAM, while extractLargeNetwork uses the
stxxl library to store the data in external memory. Use the first one for small
networks, but beware of running out of RAM. Swapping is the kiss of death. For
larger networks use extractLargeNetwork. It will be somewhat slower on the
smaller files, but way faster with large ones like the planet file.
-6
View File
@@ -1,6 +0,0 @@
- extractorLargeNetwork finishes with:
terminate called after throwing an instance of 'stxxl::resource_error'
what(): Error in function void stxxl::mutex::lock() pthread_mutex_lock(&_mutex) Invalid argument
This ist a known, albeit odd behavior that is caused by a bug in stxxl. It can be ignored. Upgrade
to version 1.3.1 of stxxl.
-159
View File
@@ -1,159 +0,0 @@
/*
* Open Source Routing Machine (OSRM) - Web (GUI) Interface
* Copyright (C) Pascal Neis, 2011
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* or see http://www.gnu.org/licenses/agpl.txt.
*/
/**
* Title: Geocode.js
* Description: JS file for geocoding
*
* @author Pascal Neis, pascal@neis-one.org
* @version 0.1 2011-05-15
*/
//======================
// OBJECTS
var HOST_GEOCODE_URL = 'http://open.mapquestapi.com';
var GEOCODE_POST = HOST_GEOCODE_URL + '/nominatim/v1/search?format=json&json_callback=showResultsGeocode';
var searchType = 'search';
var isStartPointSet = false;
var isEndPointSet = false;
//======================
// FUNCTIONS
/*
* geocodeAddress()-Function to read out textfield and send request to a OSM nominatim geocoder
*/
function geocodeAddress(tf){
var freeform;
if(tf == 'start'){
freeform = document.getElementById('tfStartSearch').value;
}
if(tf == 'end'){
freeform = document.getElementById('tfEndSearch').value;
}
document.getElementById('information').style.visibility = 'visible';
document.getElementById('information').innerHTML = '<p class="infoHL">One moment please ...</p>';
var newURL = GEOCODE_POST + "&q="+freeform;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = newURL;
document.body.appendChild(script);
}
/*
* showResultsGeocode()-Function to show the geocode result in a div
*/
function showResultsGeocode(response) {
var html = '';
var lonlat = '';
if(response){
html += '<p class="infoHL">Search Results:</p>';
html += '<table>'
var markername;
if(getStatus()=='start'){
markername = 'start'; isStartPointSet = true;
}
else if(getStatus()=='end'){
markername = 'end'; isEndPointSet = true;
}
for(var i=0; i < response.length; i++){
var result = response[i]; var resultNum = i+1;
        //odd or even ?
        var rowstyle='geocodeResultOdd';
        if(i%2==0){ rowstyle='geocodeResultEven'; }
       
html += '<tr class="'+rowstyle+'">';
html += '<td align="right" valign="top"><span class="routeSummarybold">'+resultNum+'</span></td>';
html += '<td class="'+rowstyle+'">';
if(result.display_name){
var new_display_name = result.display_name;//.replace(/,/g, ",<br />")
html += '<a href="#" onclick="javascript:setMarkerAndZoom(\''+markername+'\', new OpenLayers.LonLat('+result.lon+','+result.lat+'));">'+new_display_name.trim()+'</a>';
}
html += "</td></tr>";
//alert(result.lat + ", " + result.lon);
if(lonlat == ''){
lonlat = new OpenLayers.LonLat(result.lon,result.lat);
}
}
html += '</table>';
setMarkerAndZoom(markername, lonlat);
}
switch (searchType) {
case "search":
document.getElementById('information').style.display = "";
document.getElementById('information').innerHTML = html;
break;
}
}
/*
* setMarkerAndZoom()-Function to set a marker on the map and zoom
*/
function setMarkerAndZoom(markername,lonlat){
setMarker(markername,lonlat);
//Hack - FIXME !
lonlat.lon -= 500;
//Set Center
map.setCenter(lonlat, 15);
}
/*
* setMarker()-Function to set a marker on the map
*/
function setMarker(markername,lonlat){
lonlat.transform(EPSG_4326, EPSG_900913);
for(var i= 0; i<dragLayer.features.length; i++){
if(dragLayer.features[i].name == markername){ dragLayer.removeFeatures([dragLayer.features[i]]); }
}
var point = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat));
point.attributes = { icon: "img/start.png" };
if(markername == 'start'){
point.attributes = { icon: "img/start.png" };
}
else if(markername == 'end'){
point.attributes = { icon: "img/end.png" };
}
point.name = markername;
dragLayer.addFeatures([point]);
}
/*
* getMarkerByName()-Function to return the marker-object by a name
*/
function getMarkerByName(markerName){
for(var i= 0; i<dragLayer.features.length; i++){
if(dragLayer.features[i].name == markerName){
return dragLayer.features[i];
}
}
}
-354
View File
@@ -1,354 +0,0 @@
/*
* Open Source Routing Machine (OSRM) - Web (GUI) Interface
* Copyright (C) Pascal Neis, 2011
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* or see http://www.gnu.org/licenses/agpl.txt.
*/
/**
* Title: Map.js
* Description: JS file to show a map, for markers, left slide div, ...
*
* @author Pascal Neis, pascal@neis-one.org
* @version 0.1.1 2011-06-09
*/
//======================
// OBJECTS
//Map
var map;
//Status object for what position actually a coordinate is searched
var status = ''; //possible values [start,end]
function getStatus(){ return status; }
function setStatus(stat){ status = stat; }
//Indicator
var ISDRAGGING = false;
//Layer
var dragLayer;
var vectorLayerRoute;
var vectorLayerViaRoute;
var markersLayer;
var selectFeature;
//======================
// FUNCTIONS
/*
* init()-Function to create the map div
*/
function init(){
//Create Map
map = new OpenLayers.Map ("map", {
controls:[
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Permalink(),
new OpenLayers.Control.LayerSwitcher()],
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")
} );
//Add the base layers.
var coverageLayer = new OpenLayers.Layer.Vector("Coverage", {
style: {
strokeColor: "#000000",
strokeTransparency: 0.5,
strokeWidth: 4
}
});
if("map.project-osrm.org" == location.host) {
var coveragePointList = [
new OpenLayers.Geometry.Point(-11.99, 58.80),
new OpenLayers.Geometry.Point(-11.99, 35.30),
new OpenLayers.Geometry.Point(-7.57, 35.30),
new OpenLayers.Geometry.Point(9.22, 38.24),
new OpenLayers.Geometry.Point(15.38, 35.39),
new OpenLayers.Geometry.Point(18.92, 40.02),
new OpenLayers.Geometry.Point(15.70, 42.25),
new OpenLayers.Geometry.Point(15.70, 55.40),
new OpenLayers.Geometry.Point(30.31, 60.29),
new OpenLayers.Geometry.Point(30.31, 71.27),
new OpenLayers.Geometry.Point(21.01, 71.27),
new OpenLayers.Geometry.Point(-11.99, 58.80)
];
var line_string = new OpenLayers.Geometry.LineString(coveragePointList).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
coverageLayer.addFeatures([new OpenLayers.Feature.Vector(line_string)]);
map.addLayer(coverageLayer);
}
map.addLayer(new OpenLayers.Layer.OSM.Mapnik("Mapnik"));
map.addLayer(new OpenLayers.Layer.OSM.MapQuest("MapQuest"));
map.addLayer(new OpenLayers.Layer.OSM.Osmarender("Osmarender"));
//Add layer for the route
vectorLayerRoute = new OpenLayers.Layer.Vector("Route",{maxResolution: 156543.0339});
map.addLayer(vectorLayerRoute);
//Add layer for temporary via route
vectorLayerViaRoute = new OpenLayers.Layer.Vector("ViaRoute",{maxResolution: 156543.0339});
map.addLayer(vectorLayerViaRoute);
//Add Layerswitcher
map.addControl(new OpenLayers.Control.LayerSwitcher());
//Add Panzoombar
var panZoomBar = new OpenLayers.Control.PanZoomBar({id:'panzoombar',displayClass:'olControlPanZoomBar'})
map.addControl(panZoomBar);
//Customize the position of the panzoombar
document.getElementById('panzoombar').style.left="400px";
document.getElementById('panzoombar').style.top="25px";
//Create drag vector layer
dragLayer = new OpenLayers.Layer.Vector(
"Start/End Marker",{
styleMap: new OpenLayers.StyleMap({
// Set the external graphic and background graphic images.
externalGraphic: '${icon}',
// Makes sure the background graphic is placed correctly relative
// to the external graphic.
backgroundXOffset: -11,
backgroundYOffset: -40,
graphicXOffset: -11,
graphicYOffset: -40,
// Set the z-indexes of both graphics to make sure the background
// graphics stay in the background (shadows on top of markers looks
// odd; let's not do that).
graphicZIndex: 10,
backgroundGraphicZIndex: 11,
pointRadius: 10,
graphicWidth: 22,
graphicHeight: 40
}),
rendererOptions: {zIndexing: true}
}
);
// Add a drag feature control to move features around.
var dragFeatures = new OpenLayers.Control.DragFeature(dragLayer,
{ onDrag: function(feature, pixel){
ISDRAGGING = true;
if(feature.name == "start" || feature.name == "end") {
feature.move(map.getLonLatFromPixel(pixel));
if(!ISCALCULATING){ routing(true); }
}
if(feature.name == "via") {
computeViaRoute(pixel, true);
}
if(feature.name == "viapoint" && feature.popup) {
map.removePopup(feature.popup);
computeViaRoute(pixel, true, feature.viaIndex);
}
},
onComplete: function(feature, pixel){
ISDRAGGING = false;
if(feature.name == "start" || feature.name == "end") {
feature.move(map.getLonLatFromPixel(pixel));
routing(false);
} else if(feature.name == "via") {
console.log('finished via');
//Erase temporary point from draglayer
dragLayer.renderer.eraseFeatures([feature]);
//delete temporary route from via route Layer
vectorLayerViaRoute.removeFeatures(vectorLayerViaRoute.features);
//compute via route
computeViaRoute(pixel, false);
feature.destroy();
} else if(feature.name == "viapoint") {
//Erase temporary point from draglayer
dragLayer.renderer.eraseFeatures([feature]);
//delete via point from vector
viaPointsVector.splice(feature.viaIndex,1);
//delete temporary route from via route Layer
vectorLayerViaRoute.removeFeatures(vectorLayerViaRoute.features);
//compute via route
computeViaRoute(pixel, false);
feature.destroy();
}
},
onLeave: function(f){
if(!ISCALCULATING){ routing(false); }}
});
map.addControl(dragFeatures);
dragFeatures.activate();
map.addLayers([dragLayer]);
//Add a marker layer
markersLayer = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markersLayer);
//Add zoom event for rerouting
map.events.on({zoomend: function(e) {reroute();distanceToRoute(null);}});
// Register Callback to evaluate distance to from mouse location to route on Mousemove
map.events.on({mousemove: function(e) {distanceToRoute(e.xy);}});
// Set center of the map
if (!map.getCenter()){
map.setCenter(new OpenLayers.LonLat(600000, 6600000),6);
}
//Check if the URL contains some GET parameter, e.g. for the route
checkURL();
for(var i = 0; i < map.layers.length; i++) {
map.layers[i].transitionEffect = 'resize';
}
document.getElementById('map').oncontextmenu = function(e){
e = e?e:window.event;
if (e.preventDefault) e.preventDefault(); // For non-IE browsers.
else return false; // For IE browsers.
};
// A control class for capturing click events...
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
'double': true,
'pixelTolerance': 0,
'stopSingle': false,
'stopDouble': false
},
handleRightClicks:true,
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, this.eventMethods, this.handlerOptions
);
},
CLASS_NAME: "OpenLayers.Control.Click"
});
// Add an instance of the Click control that listens to various click events:
var oClick = new OpenLayers.Control.Click({eventMethods:{
'rightclick': function(e) {
rightClick(e);
},
'click': function(e) {
leftClick(e);
},
'dblclick': function(e) {
dblClick(e);
},
'dblrightclick': function(e) {
dblRightClick(e);
}
}});
map.addControl(oClick);
oClick.activate();
selectFeature = new OpenLayers.Control.SelectFeature(
[dragLayer],
{
clickout: true, toggle: false,
multiple: false, hover: true,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey", // shift key adds to selection
onSelect: createPopup,
onUnselect: destroyPopup
}
);
map.addControl(selectFeature);
dragLayer.events.on({
"featureselected": function(e) {
featureSelected(e);
},
"featureunselected": function(e) {
featureUnselected(e);
}
});
selectFeature.activate();
}
//Helper Functions
function checkReturn(textfieldname,e){
var evt = e || window.event;
if(!evt){ return; }
var key = 0;
if (evt.keyCode) { key = evt.keyCode; }
else if (typeof(evt.which)!= 'undefined') { key = evt.which; }
if( key == 13 && textfieldname=='start'){ setStatus('start'); geocodeAddress('start'); return; }
if( key == 13 && textfieldname=='end'){ setStatus('end'); geocodeAddress('end'); return; }
}
function closeOpenDiv(name){
if(document.getElementById(name).style.display == 'none'){ document.getElementById(name).style.display = ''; }
else{ document.getElementById(name).style.display = 'none'; }
}
//URL Functions
function checkURL(){
var getObjs = new Array();
var getString = document.location.search.substr(1,document.location.search.length);
if(getString != ''){
var getArray=getString.split('&');
console.log(getArray);
for(i=0 ; i<getArray.length ; ++i){
var v='';
var vArr = getArray[i].split('=');
if(vArr.length>1){ v = vArr[1]; }
if("via" == vArr[0]) {
var via_loc = unescape(v).split(',');
for(var j=0; j<via_loc.length; j++) { via_loc[j] = parseFloat(via_loc[j]); }
viaPointsVector.push(via_loc);
} else {
getObjs[unescape(vArr[0])]=unescape(v);
}
}
}
var fr = getObjectOfArray(getObjs, "fr");
var to = getObjectOfArray(getObjs, "to");
if(fr != 'undefined' && to != 'undefined'){
//From
var fr_pos = fr.split(',');
var fr_lonlat = new OpenLayers.LonLat(fr_pos[1],fr_pos[0]);
setMarkerAndZoom('start', fr_lonlat);
isStartPointSet = true;
//To
var to_pos = to.split(',');
var to_lonlat = new OpenLayers.LonLat(to_pos[1],to_pos[0]);
setMarker('end', to_lonlat);
isEndPointSet = true;
//Calculate the route
routing(false);
}
}
function getObjectOfArray(objects, elementName){
if(!objects[elementName]){ return 'undefined'; }
return objects[elementName];
}
-115
View File
@@ -1,115 +0,0 @@
var selectedFeature = null;
var popupCloseTimer = null;
var popupToRemove = null;
function rightClick(e) {
console.log("right click1");
if(null == selectedFeature)
return;
//alert('rightclick at '+e.xy.x+','+e.xy.y);
console.log("right click2");
}
function dblClick(e) {
//alert('dblclick at '+e.xy.x+','+e.xy.y);
}
function dblRightClick(e) {
//alert('dblrightclick at '+e.xy.x+','+e.xy.y);
}
function leftClick(e) {
//set start and target via clicks
var lonlat = map.getLonLatFromViewPortPx(e.xy);
var markername = "";
/* //routing shall not be done by left clicks
* if (e.ctrlKey || e.altKey) {
markername = "end";
isEndPointSet = true;
} else if(e.shiftKey) {
markername = "start";
isStartPointSet = true;
}
for(var i= 0; i<dragLayer.features.length; i++){
if(dragLayer.features[i].name == markername){ dragLayer.removeFeatures([dragLayer.features[i]]); }
}
var point = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat));
point.attributes = { icon: "img/start.png" };
if(markername == 'start'){
point.attributes = { icon: "img/start.png" };
}
else if(markername == 'end'){
point.attributes = { icon: "img/end.png" };
}
point.name = markername;
dragLayer.addFeatures([point]);
reroute();
*/
}
function featureSelected(f) {
if("viapoint" == f.feature.name) {
// console.log('selected ' + f.feature.name);
selectedFeature = f.feature;
}
}
function featureUnselected(f) {
if("viapoint" == f.feature.name) {
// console.log('unselected ' + f.feature.name);
selectedFeature = null;
}
}
function createPopup(feature) {
if("viapoint" != feature.name || ISDRAGGING)
return;
if(popupCloseTimer != null) {
clearInterval(popupCloseTimer);
popupCloseTimer = null;
map.removePopup(popupToRemove);
popupToRemove = null;
}
var location = feature.geometry.getBounds().getCenterLonLat().clone();
location.lon; location.lat;
feature.popup = new OpenLayers.Popup.Anchored("ViaPointInfo",
location,
new OpenLayers.Size(16,16),
'<div><a href="javascript:removeViaPoint('+ feature.viaIndex +')"><img src="img/cancel_small.png"/></a></div>',
null,
false,
destroyPopup );
feature.popup.backgroundColor = 'transparent';
feature.popup.fixedRelativePosition = true;
feature.popup.relativePosition = "tr";
map.addPopup(feature.popup, true);
}
function destroyPopup(feature) {
if(feature.popup) {
popupToRemove = feature.popup;
popupCloseTimer = setTimeout("removePopup()",2000);
}
}
function removePopup() {
if(null == popupToRemove)
return;
map.removePopup(popupToRemove);
popupToRemove = null;
popupCloseTimer = null;
}
function removeViaPoint(index) {
for(var i = 0; i < map.popups.length; i++) {
map.removePopup(map.popups[i]);
}
viaPointsVector.splice(index, 1);
reroute();
}
-366
View File
@@ -1,366 +0,0 @@
/*
* Open Source Routing Machine (OSRM) - Web (GUI) Interface
* Copyright (C) Pascal Neis, 2011
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* or see http://www.gnu.org/licenses/agpl.txt.
*/
/**
* Title: Route.js
* Description: JS file for routing
*
* @author Pascal Neis, pascal@neis-one.org
* @version 0.2 2011-06-23
*/
//======================
// OBJECTS
//Map
//var HOST_ROUTING_URL = 'http://localhost:5000/viaroute';
var HOST_ROUTING_URL = 'http://routingdemo.geofabrik.de/route-via/';
var HOST_WEBSITE = 'http://map.project-osrm.org/';//location.host
var ISCALCULATING = false;
var EPSG_4326 = new OpenLayers.Projection("EPSG:4326");
var EPSG_900913 = new OpenLayers.Projection("EPSG:900913");
var allRoutePoints = [];
//======================
// FUNCTIONS
/*
* routing()-Function to create and send route request
*/
function routing(isDragRoute){
//Check if startpoint is set
if(!isStartPointSet){
//alert("Please set your Start location first!");
document.getElementById('information').innerHTML = '<p class="infoHLRed">Please set your Start location first!</p>';
return;
}
//Check if endpoint is set
if(!isEndPointSet){
//alert("Please set your Destination first!");
document.getElementById('information').innerHTML = '<p class="infoHLRed">Please set your Destination first!</p>';
return;
}
//Check if already a route is planning
if(!isDragRoute){ ISCALCULATING = false; }
if(ISCALCULATING){ return; }
else{ ISCALCULATING = true; }
//Get Coordinates of the Start and Endpoint
var startFeat = getMarkerByName('start');
var endFeat = getMarkerByName('end');
var from = new OpenLayers.LonLat(startFeat.geometry.x,startFeat.geometry.y).transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
var to = new OpenLayers.LonLat(endFeat.geometry.x,endFeat.geometry.y).transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
//Send Request
var script = document.createElement('script');
script.type = 'text/javascript';
var callBackFunction = 'showResultsRoute';
var instructions = '&geomformat=cmp&instructions=true';
if(isDragRoute){
callBackFunction = 'showResultsDragRoute';
instructions = '&geomformat=cmp&instructions=false';
document.getElementById('information').innerHTML = '<p class="infoHL">Release mouse button to get Route Information!</p>(If no Route Summary is diplayed, press the Route!-button)';
}
script.src = HOST_ROUTING_URL + "&start="+from.lat + ',' + from.lon + '&dest=' + to.lat + ',' + to.lon;
for(var i = 0; i < viaPointsVector.length; i++) {
script.src += ('&via=' + viaPointsVector[i][0] + ',' + viaPointsVector[i][1]);
}
script.src +='&z='+this.map.getZoom()+'&output=json&jsonp='+callBackFunction+instructions;
document.body.appendChild(script);
}
/*
* reroute()-Function
*/
function reroute() {
if(!isStartPointSet || !isEndPointSet){ return; }
routing(false);
}
/*
* showResultsDragRoute()-Function to show route result for drag-route
*/
function showResultsDragRoute(response) {
   if (response) {
    //Display Route
    showRouteGeometry(response);
   }
  markersLayer.clearMarkers();
   ISCALCULATING = false;
}
/*
* showResultsRoute()-Function to show route result
*/
function showResultsRoute(response) {
   if (response) {
//Display Route
if(document.getElementById("cbNoNames").checked == true){
showNoNameStreets(response);
}
else{
showRouteGeometry(response);
}
//Save Via Points that come with route
var lengthOfArray = response.via_points.length;
var i = 0;
viaPointsVector.length = 0;
viaPointsVector = response.via_points.slice(0);
paintViaPoints();
  //Create Link of the route
var startFeat = getMarkerByName('start');
var endFeat = getMarkerByName('end');
var from = new OpenLayers.LonLat(startFeat.geometry.x,startFeat.geometry.y).transform(EPSG_900913,EPSG_4326);
var to = new OpenLayers.LonLat(endFeat.geometry.x,endFeat.geometry.y).transform(EPSG_900913,EPSG_4326);
var routelink = '<div id="routelink"><input name="routelink" type="submit" title="Get Link" onClick="createShortLink(\''+HOST_WEBSITE+'?fr='+from.lat.toFixed(6)+','+from.lon.toFixed(6)+'&to='+to.lat.toFixed(6)+','+to.lon.toFixed(6);
for(i = 0; i < viaPointsVector.length; i++) {
routelink += "&via=" + viaPointsVector[i][0] + "," + viaPointsVector[i][1];
}
routelink += '\');" value="Get Link"></div>';
//Link for the GPX Download
var gpxLink = '(<a href="'+HOST_ROUTING_URL+'&start='+from.lat.toFixed(6)+','+from.lon.toFixed(6)+'&dest='+to.lat.toFixed(6)+','+to.lon.toFixed(6)+'&z='+this.map.getZoom();
for(i = 0; i < viaPointsVector.length; i++) {
gpxLink += "&via=" + viaPointsVector[i][0] + "," + viaPointsVector[i][1];
}
gpxLink += '&output=gpx">Get GPX File</a>)';;
       //Show Route Summary
       var output = '<p class="routeSummaryHL">Some information about your Way <br> from \'<span class="routeSummaryHLlight">'+response.route_summary.start_point+'</span>\' to \'<span class="routeSummaryHLlight">'+response.route_summary.end_point+'</span>\'</p>';
       output += '<p class="routeSummary">Distance: <span class="routeSummarybold">'+response.route_summary.total_distance/1000+' km</span> - Duration: <span class="routeSummarybold">'+secondsToTime(response.route_summary.total_time)+'</span></p><p>'+routelink+'</p><p><span class="routeInstructionsHL">The Route-Instructions:</span> '+gpxLink+'</p>';
       //Show Route Instructions
        output += '<table>';
       lengthOfArray = response.route_instructions.length;
for (i = 0; i < lengthOfArray; i++) {
//console.log(response.route_instructions[i]);
        //odd or even ?
        var rowstyle='routeInstructionsOdd';
        if(i%2==0){ rowstyle='routeInstructionsEven'; }
           var indexPos = response.route_instructions[i][3];
//console.log('setting : ' + response.route_instructions[i] + ' at ' + allRoutePoints[indexPos]);
var point = allRoutePoints[indexPos];
       
           output += '<tr class="'+rowstyle+'"><td align="right" valign="top"><span class="routeSummarybold">'+(i+1)+'.</span></td><td class="'+rowstyle+'"><a href="#" class="nolinkStyle" onclick="setMapCenter(new OpenLayers.LonLat('+point.x+','+point.y+'));">'+response.route_instructions[i][0]+' on '+response.route_instructions[i][1]+' for '+getDistanceWithUnit(response.route_instructions[i][2])+'</a></td></tr>';
       }
var rowstyle='routeInstructionsOdd';
      if(i%2==0){ rowstyle='routeInstructionsEven'; }
if( lengthOfArray > 0) {
       var point = allRoutePoints[allRoutePoints.length-1];
       output += '<tr class="'+rowstyle+'"><td align="right" valign="top"><span class="routeSummarybold">'+(i+1)+'.</span></td><td class="'+rowstyle+'"><a href="#" class="nolinkStyle" onclick="setMapCenter(new OpenLayers.LonLat('+point.x+','+point.y+'));">You have reached your destination</a></td></tr>';
       }
output += '</table>';
       //alert(vectorLayerRoute.features[0].geometry.getVertices());
       
       document.getElementById('information').innerHTML = output;
   ISCALCULATING = false;
ISCALCULATINGVIA = false;
   }
}
/*
* showRouteGeometry()-Function to show route result
*/
function showRouteGeometry(response) {
if (response) {
allRoutePoints.length = 0;
    // now with compression of the route geometry
       var geometry = decodeRouteGeometry(response.route_geometry, 5);
      var lengthOfArray = geometry.length;
       var points = [];
       points.length = lengthOfArray;
       var points = [];
//delete any previously displayed via route
vectorLayerViaRoute.removeFeatures(vectorLayerViaRoute.features);
vectorLayerRoute.removeAllFeatures();
       //Create Route Layer for Display
       for (var i = 0; i < lengthOfArray; i++) {
           var point = new OpenLayers.Geometry.Point(geometry[i][1], geometry[i][0]).transform(EPSG_4326, EPSG_900913);
           allRoutePoints.push(point);
points.push(point);
           
if(i % 1024 == 0 && i>0 || i==lengthOfArray-1){
/* var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: "#000066",
strokeOpacity: 1,
strokeWidth: 9
});
var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: "#ffffff",
strokeOpacity: 0.75,
strokeWidth: 7
});
*/
var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: "#0033ff",
strokeOpacity: 0.7,
strokeWidth: 5
});
// vectorLayerRoute.addFeatures([feature2]);
// vectorLayerRoute.addFeatures([feature1]);
vectorLayerRoute.addFeatures([feature]);
points = [];
points.push(point);
}
       }
  }
}
/*
* showNoNameStreets()-Function to show route result
*/
function showNoNameStreets(response) {
   if (response) {
    allRoutePoints.length = 0;
    vectorLayerRoute.removeFeatures(vectorLayerRoute.features);
      // now with compression of the route geometry
       var geometry = decodeRouteGeometry(response.route_geometry, 5);
      var lengthOfArray = geometry.length;
       var points = [];
       points.length = lengthOfArray;
       
       //Check if a instruction has no name !
       var colors = [];
       if(true){
        var instrucLength = response.route_instructions.length;
        for (var i = 0; i < instrucLength; i++) {
        var indexPos = response.route_instructions[i][3];
        var streetName = response.route_instructions[i][1];
if(streetName == ''){ colors[indexPos] = "#FF00FF"; }
else{ colors[indexPos] = "#0033ff"; }
        }
       }
//delete any previously displayed via route
vectorLayerViaRoute.removeFeatures(vectorLayerViaRoute.features);
vectorLayerRoute.removeAllFeatures();
       
       //Create Route Layer for Display
       var color = "#0033ff";
       var changeColor = false;
       for (var i = 0; i < lengthOfArray; i++) {
           var point = new OpenLayers.Geometry.Point(geometry[i][1], geometry[i][0]).transform(EPSG_4326, EPSG_900913);
           points.push(point);
           allRoutePoints.push(point);
           if(colors[i] != undefined){ changeColor=true;}
           
if(i % 1024 == 0 && i>0 || i==lengthOfArray-1 || changeColor){
var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: color,
strokeOpacity: 0.7,
strokeWidth: 5
});
vectorLayerRoute.addFeatures([feature]);
points = [];
points.push(point);
if(colors[i] != undefined){ color = colors[i]; }
changeColor=false;
}
       }
  }
}
/*
* secondsToTime()-Function to transform seconds to a time string
*/
function secondsToTime(seconds){
seconds = parseInt(seconds);
minutes = parseInt(seconds/60);
seconds = seconds%60;
hours = parseInt(minutes/60);
minutes = minutes%60;
//return stunden+':'+minuten+':'+seconds;
if(hours==0){
return minutes+' min(s)';
}
else{
return hours+' h '+minutes+' min(s)';
}
}
/*
* getDistanceWithUnit()-Function to return a distance with units
*/
function getDistanceWithUnit(distance){
distance = parseInt(distance);
if(distance >= 1000){ return (parseInt(distance/1000))+' km'; }
else{ return distance+' m'; }
}
/*
* setMapCenter()-Function to add a marker and center the map
*/
function setMapCenter(lonlat){
//lonlat.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
//console.log('zooming to :' + lonlat);
//Add Marker
markersLayer.clearMarkers();
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon('img/marker.png',size,offset);
markersLayer.addMarker(new OpenLayers.Marker(lonlat,icon));
//Hack - FIXME !
map.setCenter(new OpenLayers.LonLat(lonlat.lon-200, lonlat.lat), 17);
}
/*
* decodeRouteGeometry()-Function to decode encoded Route Geometry
*/
function decodeRouteGeometry(encoded, precision) {
precision = Math.pow(10, -precision);
var len = encoded.length, index=0, lat=0, lng = 0, array = [];
while (index < len) {
var b, shift = 0, result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
array.push([lat * precision, lng * precision]);
}
return array;
}
/*
* createShortLink()-Function to "create" shortlink of a route
*/
function createShortLink(str){
var script = document.createElement('script');
-114
View File
@@ -1,114 +0,0 @@
/*
* Open Source Routing Machine (OSRM) - Web (GUI) Interface
* Copyright (C) Pascal Neis, 2011
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* or see http://www.gnu.org/licenses/agpl.txt.
*/
/**
* Title: Slide.js
* Description: Fixme
*
* @author Pascal Neis, pascal@neis-one.org
* @version 0.1 2011-05-15
*/
var timerlen = 5;
var slideAniLen = 250;
var timerID = new Array();
var startTime = new Array();
var obj = new Array();
var endWidth = new Array();
var moving = new Array();
var dir = new Array();
function toggleSlide(objname){
document.getElementById('panzoombar').style.top="25px";
document.getElementById('panzoombar').style.display = "none";
document.getElementById('slide').style.display = "none";
if(document.getElementById(objname).style.display == "none"){
// div is hidden, so let's slide right
slide_right(objname);
}else{
// div is not hidden, so slide left
slide_left(objname);
}
}
function slide_right(objname){
if(moving[objname]){ return; }
if(document.getElementById(objname).style.display != "none"){
return; // cannot slide right something that is already visible
}
moving[objname] = true; dir[objname] = "right"; startslide(objname);
}
function slide_left(objname){
if(moving[objname]){ return; }
if(document.getElementById(objname).style.display == "none"){
return; // cannot slide left something that is already hidden
}
moving[objname] = true; dir[objname] = "left"; startslide(objname);
}
function startslide(objname){
obj[objname] = document.getElementById(objname);
endWidth[objname] = parseInt(obj[objname].style.width);
startTime[objname] = (new Date()).getTime();
if(dir[objname] == "right"){ obj[objname].style.width = "1px"; }
obj[objname].style.display = "block";
timerID[objname] = setInterval('slidetick(\'' + objname + '\');',timerlen);
}
function slidetick(objname){
var elapsed = (new Date()).getTime() - startTime[objname];
if (elapsed > slideAniLen){ endSlide(objname); }
else {
var d = Math.round(elapsed / slideAniLen * endWidth[objname]);
if(dir[objname] == "left"){ d = endWidth[objname] - d; }
obj[objname].style.width = d + "px";
}
return;
}
function endSlide(objname){
clearInterval(timerID[objname]);
if(dir[objname] == "left"){
obj[objname].style.display = "none";
document.getElementById('panzoombar').style.left="25px";
document.getElementById('panzoombar').style.display = "";
document.getElementById('slide').style.left="5px";
document.getElementById('slide').innerHTML = "<a class=\"btn-slide\" href=\"javascript:;\" onmousedown=\"toggleSlide('data');\">>></a>";
document.getElementById('slide').style.display = "";
}
else{
document.getElementById('panzoombar').style.left="400px";
document.getElementById('panzoombar').style.display = "";document.getElementById('slide').style.left="365px";
document.getElementById('slide').innerHTML = "<a class=\"btn-slide\" href=\"javascript:;\" onmousedown=\"toggleSlide('data');\"><<</a>";
document.getElementById('slide').style.display = "";
}
obj[objname].style.width = endWidth[objname] + "px";
delete(moving[objname]);
delete(timerID[objname]);
delete(startTime[objname]);
delete(endWidth[objname]);
delete(obj[objname]);
delete(dir[objname]);
return;
}
-340
View File
@@ -1,340 +0,0 @@
/*
* Open Source Routing Machine (OSRM) - Web (GUI) Interface
* Copyright (C) Dennis Luxen, 2011
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU AFFERO General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* or see http://www.gnu.org/licenses/agpl.txt.
*/
/**
* Title: ViaRoute.js
* Description: JS file for routing with via points
*
* @author Dennis Luxen, luxen@kit.edu
* @version 0.1 June 2011
*
*/
//======================
// OBJECTS
//global timestamp to control frequency of mouse->route distance computations
var timestamp = (new Date()).getTime();
var ISCOMPUTINGDISTANCE = false;
var ISCALCULATINGVIA = false;
//var HASDELETEDTEMPORARYVIAROUTE = false;
var nearestPoint = new OpenLayers.Geometry.Point(1,1);
var nearestSegmentIndex = null;
var viaPointsVector = [];
var p0;
var temporaryViaStyle = {
fillColor: "#ffffff",
strokeColor: "#33ff33",
strokeOpacity: 0.6,
strokeWidth: 2,
pointRadius: 4,
pointerEvents: "visiblePainted"
};
var permanentViaStyle = {
fillColor: "#ffffff",
strokeColor: "#0033ff",
strokeOpacity: 0.6,
strokeWidth: 2,
pointRadius: 4,
pointerEvents: "visiblePainted"
};
//======================
//FUNCTIONS
function distanceBetweenPoint(x1, y1, x2, y2) {
var a = x1 - x2;
var b = y1 - y2;
return Math.sqrt(a*a + b*b);
}
/* Distance from a point to a line or segment.
x point's x coord
y point's y coord
x0 x coord of the line's A point
y0 y coord of the line's A point
x1 x coord of the line's B point
y1 y coord of the line's B point
o specifies if the distance should respect the limits of the segment
(overLine = true) or if it should consider the segment as an infinite
line (overLine = false), if false returns the distance from the point
to the line, otherwise the distance from the point to the segment
*/
function dotLineLength(x, y, x0, y0, x1, y1, o){
function lineLength(x, y, x0, y0){
return Math.sqrt((x -= x0) * x + (y -= y0) * y);
}
if(o && !(o = function(x, y, x0, y0, x1, y1){
if(!(x1 - x0)) return {x: x0, y: y};
else if(!(y1 - y0)) return {x: x, y: y0};
var left, tg = -1 / ((y1 - y0) / (x1 - x0));
return {x: left = (x1 * (x * tg - y + y0) + x0 * (x * - tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), y: tg * left - tg * x + y};
}(x, y, x0, y0, x1, y1), o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))){
var l1 = lineLength(x, y, x0, y0), l2 = lineLength(x, y, x1, y1);
return l1 > l2 ? l2 : l1;
}
else {
var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1;
return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
}
};
function distanceToRoute(pixel) {
if(!isStartPointSet || !isEndPointSet){
return;
}
if(ISDRAGGING) {
return;
}
if(ISCOMPUTINGDISTANCE) {
return;
}
var tempTime = (new Date()).getTime()
if( tempTime - timestamp < 25) {
return;
}
timestamp = tempTime;
if(ISCALCULATING) {
var viaPointFeature = dragLayer.getFeatureBy("name", 'via');
if(viaPointFeature != null) {
dragLayer.removeFeatures(viaPointFeature);
viaPointFeature.destroy;
}
return;
}
if(pixel == null) {
pixel.x = window.event.clientX;
pixel.y = window.event.clientY;
}
var newLonLat = map.getLonLatFromPixel(pixel);
var minimumDist = 20*Math.pow(2,(19- this.map.getZoom()));
var minimumDistToVia = 20*Math.pow(2,(19- this.map.getZoom()));
var indexToInsertViaPoint = 0;
var startFeat = getMarkerByName('start');
var endFeat = getMarkerByName('end');
var from = new OpenLayers.LonLat(startFeat.geometry.x,startFeat.geometry.y).transform(EPSG_900913, EPSG_4326);
var to = new OpenLayers.LonLat(endFeat.geometry.x,endFeat.geometry.y).transform(EPSG_900913, EPSG_4326);
var mapExtent = map.getExtent();
for(var i = 0; i < allRoutePoints.length-1; i++) {
var p1 = allRoutePoints[i];
var p2 = allRoutePoints[i+1];
if(p1.x < mapExtent.left || p1.x > mapExtent.right || p1.y < mapExtent.bottom || p1.y > mapExtent.top) {
if(p2.x < mapExtent.left || p2.x > mapExtent.right || p2.y < mapExtent.bottom || p2.y > mapExtent.top) {
continue;
}
}
//check if previous segment is closest to via point
//if yes, then we have passed a via point.
if(viaPointsVector.length > indexToInsertViaPoint && p0) {
var viaPoint = new OpenLayers.LonLat(viaPointsVector[indexToInsertViaPoint][1],viaPointsVector[indexToInsertViaPoint][0]).transform(EPSG_4326, EPSG_900913);
var dist2 = dotLineLength(viaPoint.lon, viaPoint.lat, p1.x, p1.y, p0.x, p0.y, true)
if( 0 == dist2 ) {
indexToInsertViaPoint++;
}
var tmpDist = distanceBetweenPoint(viaPoint.lat, viaPoint.lon, newLonLat.lat, newLonLat.lon);
if(tmpDist < minimumDistToVia) {
minimumDistToVia = tmpDist;
}
}
//continue if point out of view
dist = dotLineLength(newLonLat.lon, newLonLat.lat, p1.x, p1.y, p2.x, p2.y, true);
if(dist <= minimumDist) {
nearestSegmentIndex = indexToInsertViaPoint;
minimumDist = dist;
var lonDiff = (p2.x - p1.x)
var m = (p2.y - p1.y) / lonDiff;
var b = p1.y - (m * p1.x);
var m2 = m*m;
var x = (m * newLonLat.lat + newLonLat.lon - m * b) / (m2 + 1);
var y = (m2 * newLonLat.lat + m * newLonLat.lon + b) / (m2 + 1);
var r = (x - p1.x) / lonDiff;
if ( r <= 1 && r >= 0 ) {
nearestPoint.x = x;
nearestPoint.y = y;
} else {
if( r < 0 ) {
nearestPoint.x = p1.x;
nearestPoint.y = p1.y;
} if ( r > 1 ) {
nearestPoint.x = p2.x;
nearestPoint.y = p2.y;
}
}
if(p2.x == p1.x) {
nearestPoint.x = p1.x;
nearestPoint.y = newLonLat.lat;
}
}
}
var zoomFactor = Math.pow(2,(19- this.map.getZoom()));
var viaPointFeature = dragLayer.getFeatureBy("name", 'via');
if(viaPointFeature != null) {
dragLayer.removeFeatures(viaPointFeature);
viaPointFeature.destroy;
}
//too close to start or destination?
if(Math.min(distanceBetweenPoint(startFeat.geometry.x, startFeat.geometry.y, newLonLat.lon, newLonLat.lat),
distanceBetweenPoint(endFeat.geometry.x, endFeat.geometry.y, newLonLat.lon, newLonLat.lat)) < 10*zoomFactor) {
ISCOMPUTINGDISTANCE = false;
return;
}
//Are we close to the route but sufficiently far away from any existing via point?
if(minimumDist < 10*zoomFactor && minimumDistToVia > 5*zoomFactor) {
viaPointFeature = new OpenLayers.Feature.Vector( OpenLayers.Geometry.Polygon.createRegularPolygon( nearestPoint, (1.5*zoomFactor), 15, 0 ), null, temporaryViaStyle );
viaPointFeature.name = "via";
dragLayer.addFeatures( viaPointFeature );
//console.log('nearestSegmentIndex: ' + nearestSegmentIndex);
}
ISCOMPUTINGDISTANCE = false;
p0 = p1;
}
function computeViaRoute(pixel, isTemporary, skipViaPointsIndex) {
if(ISCALCULATINGVIA && isTemporary)
return;
if( nearestSegmentIndex == null ) {
//console.log('nearestSegmentIndex: ' + nearestSegmentIndex);
return;
}
if(isTemporary == null) {
isTemporary = false;
}
//So, we jumped all fences
ISCALCULATINGVIA = true;
var startFeat = getMarkerByName('start');
var endFeat = getMarkerByName('end');
var from = new OpenLayers.LonLat(startFeat.geometry.x,startFeat.geometry.y).transform(EPSG_900913, EPSG_4326);
var to = new OpenLayers.LonLat(endFeat.geometry.x,endFeat.geometry.y).transform(EPSG_900913, EPSG_4326);
var coordinate = map.getLonLatFromPixel(pixel);
var via = coordinate.transform(EPSG_900913, EPSG_4326);
var viaNodeInserted = false;
var newURL = HOST_ROUTING_URL + "&start="+from.lat + ',' + from.lon + '&dest=' + to.lat + ',' + to.lon;
newURL += '&geomformat=cmp';
for(var i = 0; i < viaPointsVector.length; i++) {
if(i == nearestSegmentIndex) { //insert new via node here
newURL += '&via=' + via.lat + ',' + via.lon;
viaNodeInserted = true;
}
if(skipViaPointsIndex == i)
continue;
newURL += '&via=' + viaPointsVector[i][0] + ',' + viaPointsVector[i][1];
}
if(false == viaNodeInserted) {
newURL += '&via=' + via.lat + ',' + via.lon;
}
newURL += '&output=json' + '&z=' + this.map.getZoom();
if(!isTemporary) {
newURL += '&instructions=true&jsonp=showResultsRoute';
} else {
newURL += '&instructions=false&jsonp=showResultsViaRoute';
}
//console.log(newURL);
var script = document.createElement('script');
script.id = 'JSONP';
script.type = 'application/javascript';
script.src = newURL;
document.body.appendChild(script);
}
function showResultsViaRoute(response) {
if (response) {
var viaRouteVector = [];
    // now with compression of the route geometry
       var geometry = decodeRouteGeometry(response.route_geometry, 5);
      var lengthOfArray = geometry.length;
       var points = [];
       points.length = lengthOfArray;
       //Create Route Layer for Display
       for (var i = 0; i < lengthOfArray; i++) {
           var point = new OpenLayers.Geometry.Point(geometry[i][1], geometry[i][0]).transform(EPSG_4326, EPSG_900913);
           allRoutePoints.push(point);
points.push(point);
           
if(i % 1024 == 0 && i>0 || i==lengthOfArray-1){
/* var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: "#006600",
strokeOpacity: 1,
strokeWidth: 9
});
*/
var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points), null, {
strokeColor: "#aaffaa",
strokeOpacity: 0.8,
strokeWidth: 7
});
// viaRouteVector.push(feature1);
viaRouteVector.push(feature);
points = [];
points.push(point);
}
       }
vectorLayerViaRoute.removeFeatures(vectorLayerViaRoute.features);
for(var i = 0; i< viaRouteVector.length; i++) {
vectorLayerViaRoute.addFeatures(viaRouteVector[i]);
}
viaRouteVector.length = 0;
ISCALCULATINGVIA = false;
}
}
function paintViaPoints() {
//remove all previous via points
var featuresToRemove = [];
for(var i = 0; i < dragLayer.features.length; i++) {
if(dragLayer.features[i].name == "viapoint" || "via" == dragLayer.features[i].name ) {
featuresToRemove.push(dragLayer.features[i]);
}
}
dragLayer.removeFeatures(featuresToRemove);
featuresToRemove.length = 0;
//paint all via points
var zoomFactor = Math.pow(2,(19- this.map.getZoom()));
//console.log('painting ' + viaPointsVector.length + ' via points');
for(var i = 0; i < viaPointsVector.length; i++) {
//console.log(viaPointsVector[i]);
var viapoint = new OpenLayers.Geometry.Point(
viaPointsVector[i][1],
viaPointsVector[i][0]);
viapoint.transform(EPSG_4326, EPSG_900913);
var viaPointFeature = new OpenLayers.Feature.Vector( OpenLayers.Geometry.Polygon.createRegularPolygon( viapoint, (1.5*zoomFactor), 20, 0 ), null, permanentViaStyle );
viaPointFeature.name = "viapoint";
viaPointFeature.viaIndex = i;
dragLayer.addFeatures( viaPointFeature )
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

-70
View File
@@ -1,70 +0,0 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>OSRM Web(GUI)Interface</title>
<meta name="description" content="OSRM Web(GUI)Interface"/>
<meta name="language" content="en" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Pascal Neis" />
<meta name="revisit-After" content="7 days" />
<meta name="distribution" content="global" />
<script src="ol/OpenLayers.js"></script>
<script src="ol/OpenStreetMap.js"></script>
<script src="Slides.js"></script>
<script src="Map.js"></script>
<script src="Route.js"></script>
<script src="ViaRoute.js"></script>
<script src="Geocode.js"></script>
<script src="MouseClick.js"></script>
<!-- <script src="osrm.js"></script> -->
<link rel="stylesheet" href="style.css" type="text/css" media="all" />
</head>
<body onload="init();">
<div id="slide" class="slide"><a class="btn-slide" href="javascript:;" onmousedown="toggleSlide('data');"><<</a></div>
<div id="data" style="width:350px;overflow:hidden;" class="data">
<div id="inner" style="width:350px;overflow:hidden;">
<div id="routing">
<!-- http://map.project-osrm.org/osrm3_small.png - http://project-osrm.org/osrm3.png -->
<img src="http://map.project-osrm.org/osrm3_small.png" style="margin-left:auto; margin-right:auto; width:200px; display:block; padding: 5px;" alt="">
<table width="100%">
<tr id="StartPoint">
<td><div class="textLabel"><img src="img/arrow-start.png" class="radioIcons" width="12" height="16" alt=""><span class="text"></span></div></td>
<td><input name="tfStartSearch" style="width:220px" type="text" id="tfStartSearch" class="tfPoints" value="Berlin" title="Search your start point!" onKeyPress="checkReturn('start',event);" >
<button name="enterStart" onclick="setStatus('start'); geocodeAddress('start');">Search</button></td>
<td rowspan="2" valign="middle">
<!-- <button name="switchStartEnd" disabled="true" id="switchStartEnd" type="button"
value="Change Start and Endpoint"onClick="changeStartEnd();"><img src="img/changePos.gif" width="9" height="22" alt="Tausche Start- und Endpunkt"><br> --></button></td>
</tr>
<tr id="EndPoint">
<td nowrap>
<div class="textLabel"><img src="img/arrow-finish.png" class="radioIcons" width="12" height="16" alt=""><span class="text"></span></div>
</td>
<td id="tdEnd">
<input name="tfEndSearch" style="width:220px" type="text" id="tfEndSearch" class="tfPoints" value="München, Altstadt" title="Search your end point!" onKeyPress="checkReturn('end',event);">
<button name="enterEnd" onclick="setStatus('end'); geocodeAddress('end');">Search</button>
</td>
</tr>
</table>
</div>
<div id="calc_route" class="calc_route"><span class="options"><a href="#" onclick="closeOpenDiv('options');">Options</a></span>
<select name="selectRoutePref" id="selectRoutePref" title="Select the route preference ..."><option value="Fastest" selected>Car (travel time)</option></select>
<input name="Submit5" type="submit" class="calculate_button" id="Calculate" title="Route!" onClick="markersLayer.clearMarkers(); routing(false);" value="Route!"></div>
<div id="options" class="options_div" style="display:none"><input class="checkbox" type="checkbox" name="cbNoNames" id="cbNoNames" value="checkbox">Highlight No Name Streets in my Route</div>
<div id="information" class="information"> <p class="infoHL">Demo Website for the <br><a target="_blank" href="http://project-osrm.org/">Open Source Routing Machine Project</a></p> </div>
<div id="thx" class="thx">GUI v0.3 110722 - OSRM hosting by <a target="_blank" href="http://www.geofabrik.de/">Geofabrik</a> - Geocoder by <a target="_blank" href="http://developer.mapquest.com/web/products/open/nominatim/">MapQuest</a></div>
</div>
</div>
<div id="map" class="map"></div>
<div class="copyright">&copy; 2011 <a target="_blank" href="http://project-osrm.org/">Project OSRM</a> - Map data <a target="_blank" href="http://creativecommons.org/licenses/by-sa/2.0/">CC-By-SA</a> <a target="_blank" href="http://www.openstreetmap.org">by OpenStreetMap</a></div>
</body>
</html>
File diff suppressed because one or more lines are too long
-141
View File
@@ -1,141 +0,0 @@
/**
* Namespace: Util.OSM
*/
OpenLayers.Util.OSM = {};
/**
* Constant: MISSING_TILE_URL
* {String} URL of image to display for missing tiles
*/
OpenLayers.Util.OSM.MISSING_TILE_URL = "http://www.openstreetmap.org/openlayers/img/404.png";
/**
* Property: originalOnImageLoadError
* {Function} Original onImageLoadError function.
*/
OpenLayers.Util.OSM.originalOnImageLoadError = OpenLayers.Util.onImageLoadError;
/**
* Function: onImageLoadError
*/
OpenLayers.Util.onImageLoadError = function() {
if (this.src.match(/^http:\/\/[abc]\.[a-z]+\.openstreetmap\.org\//)) {
this.src = OpenLayers.Util.OSM.MISSING_TILE_URL;
} else if (this.src.match(/^http:\/\/[def]\.tah\.openstreetmap\.org\//)) {
// do nothing - this layer is transparent
} else {
OpenLayers.Util.OSM.originalOnImageLoadError;
}
};
/**
* Class: OpenLayers.Layer.OSM.Mapnik
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.Mapnik = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.Mapnik
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tile.openstreetmap.org/${z}/${x}/${y}.png",
"http://b.tile.openstreetmap.org/${z}/${x}/${y}.png",
"http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({ numZoomLevels: 19, buffer: 0 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.Mapnik"
});
/**
* Class: OpenLayers.Layer.OSM.Osmarender
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.Osmarender = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.Osmarender
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
"http://b.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png",
"http://c.tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({ numZoomLevels: 18, buffer: 0 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.Osmarender"
});
/**
* Class: OpenLayers.Layer.OSM.CycleMap
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.CycleMap = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.CycleMap
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://a.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
"http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
"http://c.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({ numZoomLevels: 19, buffer: 0 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.CycleMap"
});
/**
* Class: OpenLayers.Layer.OSM.MapQuest
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.MapQuest = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.MapQuest
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
];
options = OpenLayers.Util.extend({ numZoomLevels: 19, buffer: 0 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.MapQuest"
});
-1
View File
@@ -1 +0,0 @@
This is the OpenLayers Version 2.10
Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

@@ -1,10 +0,0 @@
.olLayerGoogleCopyright {
right: 3px;
bottom: 2px;
left: auto;
}
.olLayerGooglePoweredBy {
left: 2px;
bottom: 2px;
}
@@ -1,7 +0,0 @@
.olControlZoomPanel div {
background-image: url(img/zoom-panel-NOALPHA.png);
}
.olControlPanPanel div {
background-image: url(img/pan-panel-NOALPHA.png);
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More