├── .gitignore ├── .travis.yml ├── .tx └── config ├── AUTHORS.md ├── COPYING ├── MANIFEST ├── Makefile ├── NEWS.md ├── README.md ├── RELEASING.md ├── TODO.md ├── data ├── harbour-poor-maps.desktop ├── poor-maps-108.png ├── poor-maps-128.png ├── poor-maps-256.png ├── poor-maps-86.png └── poor-maps.svg ├── geocoders ├── README.md ├── __init__.py ├── default.json ├── default.py ├── digitransit.json ├── digitransit.py ├── opencage.json ├── opencage.py ├── osmscout.json ├── osmscout.py ├── photon.json ├── photon.py └── test │ ├── __init__.py │ ├── test_default.py │ ├── test_digitransit.py │ ├── test_opencage.py │ └── test_photon.py ├── guides ├── README.md ├── __init__.py ├── foursquare.json ├── foursquare.py ├── foursquare_settings.qml ├── nominatim.json ├── nominatim.py ├── osmscout.json ├── osmscout.py └── test │ ├── __init__.py │ ├── test_foursquare.py │ └── test_nominatim.py ├── po ├── README.md ├── de_DE.po ├── es.po ├── fi.po ├── fr.po ├── hu_HU.po ├── it.po ├── nl.po ├── pl.po ├── poor-maps.pot ├── pt_BR.po ├── ru.po ├── sl_SI.po └── sv.po ├── poor ├── __init__.py ├── application.py ├── attrdict.py ├── cache.py ├── config.py ├── geocoder.py ├── guide.py ├── history.py ├── http.py ├── i18n.py ├── narrative.py ├── paths.py ├── polysimp.py ├── router.py ├── storage.py ├── test │ ├── __init__.py │ ├── test_attrdict.py │ ├── test_config.py │ ├── test_geocoder.py │ ├── test_guide.py │ ├── test_http.py │ ├── test_polysimp.py │ ├── test_router.py │ ├── test_tilesource.py │ ├── test_util.py │ ├── test_voice.py │ └── unittest.py ├── tilecollection.py ├── tilesource.py ├── util.py └── voice.py ├── qml ├── AboutPage.qml ├── BasemapPage.qml ├── Bubble.qml ├── BubbleButton.qml ├── BusyModal.qml ├── CachePage.qml ├── Config.qml ├── Cover.qml ├── CoverTile.qml ├── DummyPage.qml ├── GeocodePage.qml ├── GeocoderPage.qml ├── GeocodingResultsPage.qml ├── GuidePage.qml ├── IconListItem.qml ├── ListItemLabel.qml ├── ManeuverMarker.qml ├── Map.qml ├── MapMouseArea.qml ├── MapPlugin.qml ├── MapTimer.qml ├── MenuButton.qml ├── MenuPage.qml ├── Meters.qml ├── NarrationTimer.qml ├── NarrativePage.qml ├── NavigationBlock.qml ├── NavigationPage.qml ├── NavigationStatus.qml ├── NearbyPage.qml ├── NearbyResultsPage.qml ├── NorthArrow.qml ├── Notification.qml ├── OverlayPage.qml ├── PlaceTypePage.qml ├── PoiMarker.qml ├── PositionMarker.qml ├── PositionSource.qml ├── PreferencesPage.qml ├── Python.qml ├── Root.qml ├── Route.qml ├── RoutePage.qml ├── RoutePointPage.qml ├── RouterPage.qml ├── ScaleBar.qml ├── SharePage.qml ├── Spacer.qml ├── Tile.qml ├── ToolItem.qml ├── icons │ ├── bubble-arrow.svg │ ├── bubble-arrow@1.00.png │ ├── bubble-arrow@1.25.png │ ├── bubble-arrow@1.50.png │ ├── bubble-arrow@1.75.png │ ├── bubble-arrow@2.00.png │ ├── cover.png │ ├── cover.svg │ ├── maneuver.svg │ ├── maneuver@1.00.png │ ├── maneuver@1.25.png │ ├── maneuver@1.50.png │ ├── maneuver@1.75.png │ ├── maneuver@2.00.png │ ├── menu.svg │ ├── menu@1.00.png │ ├── menu@1.25.png │ ├── menu@1.50.png │ ├── menu@1.75.png │ ├── menu@2.00.png │ ├── navigation │ │ ├── README.md │ │ ├── arrive-left.svg │ │ ├── arrive-right.svg │ │ ├── arrive-straight.svg │ │ ├── arrive.svg │ │ ├── close.svg │ │ ├── continue-left.svg │ │ ├── continue-right.svg │ │ ├── continue-slight-left.svg │ │ ├── continue-slight-right.svg │ │ ├── continue-straight.svg │ │ ├── continue-uturn.svg │ │ ├── continue.svg │ │ ├── depart-left.svg │ │ ├── depart-right.svg │ │ ├── depart-straight.svg │ │ ├── depart.svg │ │ ├── end-of-road-left.svg │ │ ├── end-of-road-right.svg │ │ ├── ferry.svg │ │ ├── flag.svg │ │ ├── fork-left.svg │ │ ├── fork-right.svg │ │ ├── fork-slight-left.svg │ │ ├── fork-slight-right.svg │ │ ├── fork-straight.svg │ │ ├── fork.svg │ │ ├── invalid-left.svg │ │ ├── invalid-right.svg │ │ ├── invalid-slight-left.svg │ │ ├── invalid-slight-right.svg │ │ ├── invalid-straight.svg │ │ ├── invalid-uturn.svg │ │ ├── invalid.svg │ │ ├── merge-left.svg │ │ ├── merge-right.svg │ │ ├── merge-slight-left.svg │ │ ├── merge-slight-right.svg │ │ ├── merge-straight.svg │ │ ├── new-name-left.svg │ │ ├── new-name-right.svg │ │ ├── new-name-sharp-left.svg │ │ ├── new-name-sharp-right.svg │ │ ├── new-name-slight-left.svg │ │ ├── new-name-slight-right.svg │ │ ├── new-name-straight.svg │ │ ├── notificaiton-sharp-right.svg │ │ ├── notification-left.svg │ │ ├── notification-right.svg │ │ ├── notification-sharp-left.svg │ │ ├── notification-slight-left.svg │ │ ├── notification-slight-right.svg │ │ ├── notification-straight.svg │ │ ├── off-ramp-left.svg │ │ ├── off-ramp-right.svg │ │ ├── off-ramp-slight-left.svg │ │ ├── off-ramp-slight-right.svg │ │ ├── on-ramp-left.svg │ │ ├── on-ramp-right.svg │ │ ├── on-ramp-sharp-left.svg │ │ ├── on-ramp-sharp-right.svg │ │ ├── on-ramp-slight-left.svg │ │ ├── on-ramp-slight-right.svg │ │ ├── on-ramp-straight.svg │ │ ├── rotary-left.svg │ │ ├── rotary-right.svg │ │ ├── rotary-sharp-left.svg │ │ ├── rotary-sharp-right.svg │ │ ├── rotary-slight-left.svg │ │ ├── rotary-slight-right.svg │ │ ├── rotary-straight.svg │ │ ├── rotary.svg │ │ ├── roundabout-left.svg │ │ ├── roundabout-right.svg │ │ ├── roundabout-sharp-left.svg │ │ ├── roundabout-sharp-right.svg │ │ ├── roundabout-slight-left.svg │ │ ├── roundabout-slight-right.svg │ │ ├── roundabout-straight.svg │ │ ├── roundabout.svg │ │ ├── turn-left.svg │ │ ├── turn-right.svg │ │ ├── turn-sharp-left.svg │ │ ├── turn-sharp-right.svg │ │ ├── turn-slight-left.svg │ │ ├── turn-slight-right.svg │ │ ├── turn-straight.svg │ │ ├── updown.svg │ │ └── uturn.svg │ ├── node.svg │ ├── node@1.00.png │ ├── node@1.25.png │ ├── node@1.50.png │ ├── node@1.75.png │ ├── node@2.00.png │ ├── north.svg │ ├── north@1.00.png │ ├── north@1.25.png │ ├── north@1.50.png │ ├── north@1.75.png │ ├── north@2.00.png │ ├── poi.svg │ ├── poi@1.00.png │ ├── poi@1.25.png │ ├── poi@1.50.png │ ├── poi@1.75.png │ ├── poi@2.00.png │ ├── position-direction.svg │ ├── position-direction@1.00.png │ ├── position-direction@1.25.png │ ├── position-direction@1.50.png │ ├── position-direction@1.75.png │ ├── position-direction@2.00.png │ ├── position.svg │ ├── position@1.00.png │ ├── position@1.25.png │ ├── position@1.50.png │ ├── position@1.75.png │ ├── position@2.00.png │ ├── svg2png │ ├── tile.png │ └── tile.svg ├── js │ └── util.js └── poor-maps.qml ├── routers ├── README.md ├── __init__.py ├── digitransit.graphql ├── digitransit.json ├── digitransit.py ├── digitransit │ ├── README.md │ ├── airplane.svg │ ├── airplane@1.00.png │ ├── airplane@1.25.png │ ├── airplane@1.50.png │ ├── airplane@1.75.png │ ├── airplane@2.00.png │ ├── bus.svg │ ├── bus@1.00.png │ ├── bus@1.25.png │ ├── bus@1.50.png │ ├── bus@1.75.png │ ├── bus@2.00.png │ ├── citybike.svg │ ├── citybike@1.00.png │ ├── citybike@1.25.png │ ├── citybike@1.50.png │ ├── citybike@1.75.png │ ├── citybike@2.00.png │ ├── ferry.svg │ ├── ferry@1.00.png │ ├── ferry@1.25.png │ ├── ferry@1.50.png │ ├── ferry@1.75.png │ ├── ferry@2.00.png │ ├── metro.svg │ ├── metro@1.00.png │ ├── metro@1.25.png │ ├── metro@1.50.png │ ├── metro@1.75.png │ ├── metro@2.00.png │ ├── svg2png │ ├── train.svg │ ├── train@1.00.png │ ├── train@1.25.png │ ├── train@1.50.png │ ├── train@1.75.png │ ├── train@2.00.png │ ├── tram.svg │ ├── tram@1.00.png │ ├── tram@1.25.png │ ├── tram@1.50.png │ ├── tram@1.75.png │ └── tram@2.00.png ├── digitransit_results.qml ├── digitransit_settings.qml ├── mapquest_open.json ├── mapquest_open.py ├── mapquest_open_results.qml ├── mapquest_open_settings.qml ├── osmscout.json ├── osmscout.py ├── osmscout_results.qml ├── osmscout_settings.qml ├── osrm.json ├── osrm.py ├── osrm_results.qml └── test │ ├── __init__.py │ ├── test_digitransit.py │ ├── test_mapquest_open.py │ └── test_osrm.py ├── rpm └── harbour-poor-maps.spec ├── tilesources ├── README.md ├── __init__.py ├── aster_gdem_srtm_@1x.json ├── cartago_streets_@1x.json ├── cartago_streets_@2x.json ├── cartago_streets_@3x.json ├── cartago_streets_@4x.json ├── cartago_streets_english_@1x.json ├── cartago_streets_english_@2x.json ├── cartago_streets_english_@3x.json ├── cartago_streets_english_@4x.json ├── hikebikemap_@1x.json ├── hsl_@1x.json ├── hsl_@2x.json ├── mapbox_outdoors_@1x.json ├── mapbox_outdoors_@2x.json ├── mapbox_outdoors_gl_@1x.json ├── mapbox_outdoors_gl_@2x.json ├── mapbox_streets_@1x.json ├── mapbox_streets_@2x.json ├── mapbox_streets_gl_@1x.json ├── mapbox_streets_gl_@2x.json ├── opencyclemap_@1x.json ├── opencyclemap_@2x.json ├── openseamap_@1x.json ├── openstreetmap_@1x.json ├── opnvkarte_@1x.json ├── osmscout_car_day_@1x.json ├── osmscout_car_day_@2x.json ├── osmscout_car_night_@1x.json ├── osmscout_car_night_@2x.json ├── osmscout_day_@1x.json ├── osmscout_day_@2x.json ├── osmscout_night_@1x.json ├── osmscout_night_@2x.json ├── quadkey.py ├── slippy.py ├── slippy_elliptical.py ├── sputnik_@1x.json ├── sputnik_@2x.json ├── test │ ├── __init__.py │ ├── test_quadkey.py │ ├── test_slippy.py │ ├── test_slippy_elliptical.py │ └── test_urls.py ├── thunderforest_transport_@1x.json └── thunderforest_transport_@2x.json └── tools ├── check-translations ├── release └── update-translations /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .cache 3 | .tern-port 4 | __pycache__ 5 | dist 6 | rpm/*.rpm 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - 3.4 4 | - 3.5 5 | before_install: 6 | - sudo apt-get update -qq 7 | - sudo apt-get install -y rpm 8 | script: 9 | - make clean 10 | - make dist 11 | - make rpm 12 | - make test 13 | notifications: 14 | on_success: change 15 | on_failure: change 16 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [poor-maps.poor-mapspot] 5 | file_filter = po/.po 6 | source_file = po/poor-maps.pot 7 | source_lang = en 8 | type = PO 9 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Osmo Salomaa 2 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | data 2 | geocoders 3 | guides 4 | po 5 | poor 6 | qml 7 | routers 8 | rpm 9 | tilesources 10 | AUTHORS.md 11 | COPYING 12 | Makefile 13 | MANIFEST 14 | NEWS.md 15 | README.md 16 | RELEASING.md 17 | TODO.md 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Poor Maps 2 | ========= 3 | 4 | ![Not Maintained](https://img.shields.io/maintenance/no/2018.svg) 5 | 6 | Poor Maps is an application for Sailfish OS to display tiled maps (e.g. 7 | OpenStreetMap), places and routes with a flexible selection of data and 8 | service providers. 9 | 10 | Poor Maps is free software released under the GNU General Public License 11 | (GPL), see the file [`COPYING`](COPYING) for details. 12 | 13 | For testing purposes you can just run `qmlscene qml/poor-maps.qml`. For 14 | installation, you can build the RPM package with command `make rpm`. You 15 | don't need an SDK to build the RPM, only basic tools: `make`, 16 | `rpmbuild`, `gettext` and `linguist` from `qttools` 17 | -------------------------------------------------------------------------------- /RELEASING.md: -------------------------------------------------------------------------------- 1 | Releasing a New Version 2 | ======================= 3 | 4 | ```bash 5 | # Update translations. 6 | make pot 7 | msgmerge -UN po/fi.po po/poor-maps.pot 8 | emacs po/fi.po 9 | tx push -s 10 | tx push -tf --no-interactive -l fi 11 | tx pull -a --minimum-perc=95 12 | sed -i "s/charset=CHARSET/charset=UTF-8/" po/*.po 13 | tools/check-translations 14 | tools/check-translations | grep % 15 | git add po/*.po po/*.pot 16 | git commit -m "Update translations" 17 | 18 | # Check, test, do final edits and release. 19 | make check; make test 20 | emacs poor/__init__.py rpm/*.spec Makefile 21 | emacs NEWS.md TODO.md 22 | make rpm 23 | rpmvalidation.sh rpm/*.noarch.rpm 24 | install-rpm-on-jolla rpm/*.noarch.rpm 25 | tools/release 26 | ``` 27 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/TODO.md -------------------------------------------------------------------------------- /data/harbour-poor-maps.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Poor Maps 3 | Exec=sailfish-qml harbour-poor-maps 4 | Icon=harbour-poor-maps 5 | Type=Application 6 | X-Nemo-Application-Type=silica-qt5 7 | -------------------------------------------------------------------------------- /data/poor-maps-108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/data/poor-maps-108.png -------------------------------------------------------------------------------- /data/poor-maps-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/data/poor-maps-128.png -------------------------------------------------------------------------------- /data/poor-maps-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/data/poor-maps-256.png -------------------------------------------------------------------------------- /data/poor-maps-86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/data/poor-maps-86.png -------------------------------------------------------------------------------- /geocoders/README.md: -------------------------------------------------------------------------------- 1 | Implementing a Geocoder 2 | ======================= 3 | 4 | ## API 5 | 6 | To implement a geocoder, you need to write two files: a JSON metadata 7 | file and a Python file that implements the `geocode` function. The 8 | `geocode` function should given a string query return a list of 9 | dictionaries of geocoding results, with each dictionary having keys 10 | `title`, `description`, `x` and `y`, example below. 11 | 12 | ```python 13 | [ 14 | { 15 | "title": "Erottaja", 16 | "description": "Mannerheimintie, 00120 Helsinki, Finland", 17 | "x": 24.9434147, 18 | "y": 60.1669202, 19 | }, 20 | ... 21 | ] 22 | ``` 23 | 24 | ## Tips 25 | 26 | To download data you should always use `poor.http.get` or 27 | `poor.http.get_json` in order to use Poor's user-agent and default 28 | timeout and error handling. You might also find `poor.AttrDict`, a 29 | dictionary with attribute access to keys, convenient when working with 30 | JSON data. 31 | 32 | Use `~/.local/share/harbour-poor-maps/geocoders` as a local installation 33 | directory in which to place your files. Restart Poor, and your geocoder 34 | should be loaded, listed and available for use. During development, 35 | consider keeping your files under the Poor Maps source tree and using 36 | the Python interpreter or a test script, e.g. 37 | 38 | ```python 39 | >>> import poor 40 | >>> geocoder = poor.Geocoder("my_geocoder") 41 | >>> geocoder.geocode("erottaja, helsinki") 42 | ``` 43 | 44 | and qmlscene (`qmlscene qml/poor-maps.qml`) for testing. 45 | -------------------------------------------------------------------------------- /geocoders/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /geocoders/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap and others", 3 | "description": "Search using a priority list of providers", 4 | "hidden": true, 5 | "name": "Default", 6 | "source": "Various" 7 | } 8 | -------------------------------------------------------------------------------- /geocoders/default.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """ 19 | Geocoding using a priority list of providers. 20 | 21 | This is an error tolerant geocoder that falls back on a another provider 22 | if the first one tried does not work. 23 | """ 24 | 25 | import poor 26 | 27 | providers = ["opencage", "photon"] 28 | 29 | def geocode(query, params): 30 | """Return a list of dictionaries of places matching `query`.""" 31 | for i, provider in enumerate(providers): 32 | geocoder = poor.Geocoder(provider) 33 | # 'geocode' returns an empty list or a dict(error=True) 34 | # in case of no results or an error. 35 | results = geocoder.geocode(query, params) 36 | if results and isinstance(results, list): 37 | if i > 0: providers.insert(0, providers.pop(i)) 38 | return results 39 | # All providers failed. 40 | return [] 41 | -------------------------------------------------------------------------------- /geocoders/digitransit.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenAddresses, Who’s on First, OpenStreetMap, MML", 3 | "_description": "Search in Finland", 4 | "name": "Digitransit", 5 | "source": "digitransit.fi" 6 | } 7 | -------------------------------------------------------------------------------- /geocoders/digitransit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2016 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """ 19 | Geocoding in Finland using Digitransit. 20 | 21 | https://digitransit.fi/en/developers/services-and-apis/2-geocoding-api/address-search/ 22 | """ 23 | 24 | import copy 25 | import poor 26 | import urllib.parse 27 | 28 | URL = "http://api.digitransit.fi/geocoding/v1/search?text={query}&size={limit}&lang={lang}" 29 | cache = {} 30 | 31 | def geocode(query, params): 32 | """Return a list of dictionaries of places matching `query`.""" 33 | query = urllib.parse.quote_plus(query) 34 | limit = params.get("limit", 10) 35 | lang = poor.util.get_default_language("fi") 36 | lang = (lang if lang in ("fi", "sv") else "fi") 37 | url = URL.format(**locals()) 38 | with poor.util.silent(KeyError): 39 | return copy.deepcopy(cache[url]) 40 | results = poor.http.get_json(url)["features"] 41 | results = list(map(poor.AttrDict, results)) 42 | results = [dict( 43 | title=result.properties.name, 44 | description=parse_description(result.properties), 45 | x=float(result.geometry.coordinates[0]), 46 | y=float(result.geometry.coordinates[1]), 47 | ) for result in results] 48 | if results and results[0]: 49 | cache[url] = copy.deepcopy(results) 50 | return results 51 | 52 | def parse_description(props): 53 | """Parse description from geocoding result properties.""" 54 | items = [] 55 | with poor.util.silent(Exception): 56 | items.append(props.locality) 57 | with poor.util.silent(Exception): 58 | items.append(props.region) 59 | with poor.util.silent(Exception): 60 | items.append(props.country) 61 | return ", ".join(items) 62 | -------------------------------------------------------------------------------- /geocoders/opencage.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap, DataScienceToolkit, Flickr Shapefiles, GeoNames, Natural Earth, OpenGeoCode, Quattroshapes, Twofishes, Yahoo GeoPlanet", 3 | "_description": "Search based on open data sources", 4 | "name": "OpenCage", 5 | "source": "geocoder.opencagedata.com" 6 | } 7 | -------------------------------------------------------------------------------- /geocoders/osmscout.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Search based on OpenStreetMap data", 4 | "name": "OSM Scout", 5 | "requires": ["harbour-osmscout-server"], 6 | "_source": "OSM Scout offline server" 7 | } 8 | -------------------------------------------------------------------------------- /geocoders/osmscout.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2016 rinigus 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """ 19 | Geocoding using OSM Scout Server Geocoder. 20 | 21 | https://github.com/rinigus/osmscout-server 22 | """ 23 | 24 | import copy 25 | import poor 26 | import urllib.parse 27 | 28 | URL = "http://localhost:8553/v1/search?limit={limit}&search={query}" 29 | cache = {} 30 | 31 | def geocode(query, params): 32 | """Return a list of dictionaries of places matching `query`.""" 33 | query = urllib.parse.quote_plus(query) 34 | limit = params.get("limit", 25) 35 | url = URL.format(**locals()) 36 | with poor.util.silent(KeyError): 37 | return copy.deepcopy(cache[url]) 38 | results = poor.http.get_json(url) 39 | results = list(map(poor.AttrDict, results)) 40 | results = [dict( 41 | title=result.title, 42 | description=parse_description(result), 43 | x=float(result.lng), 44 | y=float(result.lat), 45 | ) for result in results] 46 | if results and results[0]: 47 | cache[url] = copy.deepcopy(results) 48 | return results 49 | 50 | def parse_description(result): 51 | """Parse description from geocoding result.""" 52 | items = [] 53 | with poor.util.silent(Exception): 54 | type = result.type 55 | type = type.replace("amenity", "") 56 | type = type.replace("_", " ").strip() 57 | items.append(type.capitalize()) 58 | with poor.util.silent(Exception): 59 | items.append(result.admin_region) 60 | return ", ".join(items) or "–" 61 | -------------------------------------------------------------------------------- /geocoders/photon.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Search based on OpenStreetMap data", 4 | "name": "Photon", 5 | "source": "komoot.de" 6 | } 7 | -------------------------------------------------------------------------------- /geocoders/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/geocoders/test/__init__.py -------------------------------------------------------------------------------- /geocoders/test/test_default.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.geocoder = poor.Geocoder("default") 25 | 26 | def test_geocode(self): 27 | results = self.geocoder.geocode("seurasaari, helsinki") 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.title 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /geocoders/test/test_digitransit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.geocoder = poor.Geocoder("digitransit") 25 | 26 | def test_geocode(self): 27 | results = self.geocoder.geocode("kasarmitori, helsinki") 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.title 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /geocoders/test/test_opencage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2016 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.geocoder = poor.Geocoder("opencage") 25 | 26 | def test_geocode(self): 27 | results = self.geocoder.geocode("viiskulma, helsinki") 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.title 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /geocoders/test/test_photon.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2016 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.geocoder = poor.Geocoder("photon") 25 | 26 | # XXX: Photon demo server is often over capacity. 27 | def __test_geocode(self): 28 | results = self.geocoder.geocode("vallisaari, helsinki") 29 | results = list(map(poor.AttrDict, results)) 30 | assert results 31 | for result in results: 32 | assert result.title 33 | assert result.x 34 | assert result.y 35 | -------------------------------------------------------------------------------- /guides/README.md: -------------------------------------------------------------------------------- 1 | Implementing a Venue Guide 2 | ========================== 3 | 4 | By a venue guide we mean a service that provides a geocoded list of 5 | venues by type (e.g. restaurant) around a given location and possibly 6 | details, reviews, ratings, etc. of those venues. 7 | 8 | ## API 9 | 10 | To implement a venue guide you need to write a JSON metadata file, a 11 | Python file that implements the `nearby` function and possibly a QML 12 | settings file. The `nearby` function should given a string query, a 13 | point and a radius return coordinates of the point and a list of 14 | dictionaries of venues, with each dictionary having keys `title`, 15 | `description`, `x` and `y`, example below. The point to search near can 16 | be either a string (an address, a landmark, etc.) or a two-element tuple 17 | or list of (x, y) coordinates. 18 | 19 | ```python 20 | [ 21 | { 22 | "title": "Ragu", 23 | "description": "8.9/10, Restaurant, Ludviginkatu 3-5...", 24 | "x": 24.944736480080568, 25 | "y": 60.165858355160665, 26 | }, 27 | ... 28 | ] 29 | ``` 30 | 31 | The QML settings file (`*_settings.qml`) is optional; it can be used to 32 | provide a column of guide-specific settings, which are shown in Poor's 33 | nearby page below the standard selectors. To pass settings to your 34 | guide, you have two options. If those settings are to be saved across 35 | sessions, define a `CONF_DEFAULTS` attribute in your Python code; it 36 | will be automatically passed to and available at `poor.conf`. For 37 | settings which shouldn't be saved across sessions, you can use 38 | `page.params` in your QML. 39 | 40 | ## Tips 41 | 42 | To download data you should always use `poor.http.get` or 43 | `poor.http.get_json` in order to use Poor's user-agent and default 44 | timeout and error handling. You might also find `poor.AttrDict`, a 45 | dictionary with attribute access to keys, convenient when working with 46 | JSON data. 47 | 48 | Use `~/.local/share/harbour-poor-maps/guides` as a local installation 49 | directory in which to place your files. Restart Poor, and your guide 50 | should be loaded, listed and available for use. During development, 51 | consider keeping your files under the Poor Maps source tree and using 52 | the Python interpreter or a test script, e.g. 53 | 54 | ```python 55 | >>> import poor 56 | >>> guide = poor.Guide("my_guide") 57 | >>> guide.nearby("restaurant", "erottaja, helsinki", 1000) 58 | ``` 59 | 60 | and qmlscene (`qmlscene qml/poor-maps.qml`) for testing. 61 | -------------------------------------------------------------------------------- /guides/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/guides/__init__.py -------------------------------------------------------------------------------- /guides/foursquare.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © Foursquare", 3 | "_description": "Venues listed and reviewed by Foursquare users", 4 | "name": "Foursquare", 5 | "source": "foursquare.com" 6 | } 7 | -------------------------------------------------------------------------------- /guides/foursquare_settings.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | 22 | Column { 23 | 24 | ComboBox { 25 | id: closestComboBox 26 | label: app.tr("Prefer") 27 | menu: ContextMenu { 28 | MenuItem { text: app.tr("Closest") } 29 | MenuItem { text: app.tr("Best") } 30 | } 31 | Component.onCompleted: { 32 | var closest = app.conf.get("guides.foursquare.sort_by_distance"); 33 | closestComboBox.currentIndex = closest ? 0 : 1; 34 | } 35 | onCurrentIndexChanged: { 36 | var closest = closestComboBox.currentIndex === 0; 37 | app.conf.set("guides.foursquare.sort_by_distance", closest); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /guides/nominatim.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Points of interest from OpenStreetMap data", 4 | "name": "MapQuest Nominatim", 5 | "source": "open.mapquest.com" 6 | } 7 | -------------------------------------------------------------------------------- /guides/osmscout.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Points of interest from OpenStreetMap data", 4 | "name": "OSM Scout", 5 | "requires": ["harbour-osmscout-server"], 6 | "_source": "OSM Scout offline server" 7 | } 8 | -------------------------------------------------------------------------------- /guides/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/guides/test/__init__.py -------------------------------------------------------------------------------- /guides/test/test_foursquare.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.guide = poor.Guide("foursquare") 25 | 26 | def test_geocode(self): 27 | results = self.guide.nearby("restaurant", "tapiola, espoo", 1000) 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.title 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /guides/test/test_nominatim.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.guide = poor.Guide("nominatim") 25 | 26 | def test_geocode(self): 27 | results = self.guide.nearby("restaurant", "olari, espoo", 1000) 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.title 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /po/README.md: -------------------------------------------------------------------------------- 1 | Translating Poor Maps 2 | ===================== 3 | 4 | Translations are available at [Transifex][1]. Please use that to add and 5 | update translations. Try to keep your translation consistent with the 6 | [Sailfish OS translations][2] and [language-specific style guides][3]. 7 | 8 | [1]: https://www.transifex.com/otsaloma/poor-maps/ 9 | [2]: https://sailfishos.org/wiki/Translate_the_OS 10 | [3]: https://sailfishos.org/wiki/Translate_the_OS#Style 11 | 12 | ## Testing Your Translation 13 | 14 | If you wish to test your translation (e.g. for context or brevity) 15 | before it's included in a public release, the easiest way is to add your 16 | translation to the Poor Maps source tree, build the RPM and install it. 17 | 18 | 1. Download your translation from Transifex with the link "Download for 19 | use". You should find it via the language list, or 20 | use [this full link][dl-po], replacing `fi` with your language code. 21 | 22 | 1. Download Poor Maps from GitHub. Usually you'll probably want the 23 | source code of the latest release, which can be downloaded from 24 | the [releases][releases] page. 25 | 26 | 1. Unpack the downloaded source code and place your translation in the 27 | `po` directory with the correct short language and possibly country 28 | code, e.g. `fi.po` or `pt_BR.po`. 29 | 30 | 1. Run command `make rpm` in the source directory. You'll need `make`, 31 | `rpmbuild`, `gettext` and `linguist` from `qttools`. You'll find the 32 | resulting RPM under the `rpm` directory. Copy that to your device and 33 | install e.g. via the File Browser app or `pkcon install-local ...` at 34 | a command line. 35 | 36 | [dl-po]: https://www.transifex.com/otsaloma/poor-maps/poor-mapspot/fi/download/for_use/ 37 | [releases]: https://github.com/otsaloma/poor-maps/releases 38 | -------------------------------------------------------------------------------- /poor/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """An application to display maps and stuff.""" 19 | 20 | __version__ = "0.34.3" 21 | 22 | try: 23 | import pyotherside 24 | except ImportError: 25 | import sys 26 | # Allow testing Python backend alone. 27 | print("PyOtherSide not found, continuing anyway!", 28 | file=sys.stderr) 29 | class pyotherside: 30 | def atexit(*args): pass 31 | def send(*args): pass 32 | sys.modules["pyotherside"] = pyotherside() 33 | 34 | from poor.paths import * 35 | from poor import i18n 36 | from poor import util 37 | from poor import cache 38 | from poor import http 39 | from poor import polysimp 40 | from poor import storage 41 | from poor.attrdict import * 42 | from poor.config import * 43 | conf = ConfigurationStore() 44 | from poor.tilecollection import * 45 | from poor.tilesource import * 46 | from poor.geocoder import * 47 | from poor.guide import * 48 | from poor.history import * 49 | from poor.router import * 50 | from poor.voice import * 51 | from poor.narrative import * 52 | from poor.application import * 53 | 54 | def get_default_basemap(pixel_ratio): 55 | """Return default basemap for `pixel_ratio`.""" 56 | if pixel_ratio >= 3.5: 57 | return "cartago_streets_@4x" 58 | if pixel_ratio >= 2.5: 59 | return "cartago_streets_@3x" 60 | if pixel_ratio >= 1.5: 61 | return "mapbox_streets_gl_@2x" 62 | return "mapbox_streets_gl_@1x" 63 | 64 | def main(pixel_ratio=1): 65 | """Initialize application.""" 66 | import poor.config 67 | basemap = get_default_basemap(pixel_ratio) 68 | poor.config.DEFAULTS["basemap"] = basemap 69 | conf.read() 70 | global app 71 | app = Application() 72 | -------------------------------------------------------------------------------- /poor/i18n.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2016 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """Internationalization functions.""" 19 | 20 | import gettext 21 | import locale 22 | import poor 23 | 24 | _translation = gettext.translation( 25 | "poor-maps", 26 | localedir=poor.LOCALE_DIR, 27 | languages=[locale.getdefaultlocale()[0] or ""], 28 | fallback=True) 29 | 30 | _foreign_translations = {} 31 | 32 | def _(message): 33 | """Return the localized translation of `message`.""" 34 | return _translation.gettext(message) 35 | 36 | def __(message, language): 37 | """Return the translation of `message` to `language`.""" 38 | # Try to account for differences between provider API languages 39 | # and our translations, allowing some amount of fuzziness, e.g. 40 | # for German try "de" and "de_DE" in addition to the requested. 41 | plain = language.split("_")[0] 42 | origin = "{}_{}".format(plain, plain.upper()) 43 | if not language in _foreign_translations: 44 | _foreign_translations[language] = gettext.translation( 45 | "poor-maps", 46 | localedir=poor.LOCALE_DIR, 47 | languages=[language, plain, origin], 48 | fallback=True) 49 | 50 | translation = _foreign_translations[language] 51 | return translation.gettext(message) 52 | -------------------------------------------------------------------------------- /poor/paths.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """Standard paths to files.""" 19 | 20 | import os 21 | 22 | __all__ = ("CACHE_HOME_DIR", "CONFIG_HOME_DIR", "DATA_DIR", "DATA_HOME_DIR", "LOCALE_DIR") 23 | 24 | XDG_CACHE_HOME = os.path.expanduser(os.getenv("XDG_CACHE_HOME", "~/.cache")) 25 | XDG_CONFIG_HOME = os.path.expanduser(os.getenv("XDG_CONFIG_HOME", "~/.config")) 26 | XDG_DATA_HOME = os.path.expanduser(os.getenv("XDG_DATA_HOME", "~/.local/share")) 27 | 28 | CACHE_HOME_DIR = os.path.join(XDG_CACHE_HOME, "harbour-poor-maps") 29 | CONFIG_HOME_DIR = os.path.join(XDG_CONFIG_HOME, "harbour-poor-maps") 30 | DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) 31 | DATA_HOME_DIR = os.path.join(XDG_DATA_HOME, "harbour-poor-maps") 32 | LOCALE_DIR = "/usr/share/harbour-poor-maps/locale" 33 | -------------------------------------------------------------------------------- /poor/test/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | from poor.test.unittest import * 19 | -------------------------------------------------------------------------------- /poor/test/test_geocoder.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestGeocoder(poor.test.TestCase): 22 | 23 | def test___new____no(self): 24 | a = poor.Geocoder("digitransit") 25 | b = poor.Geocoder("opencage") 26 | assert not a is b 27 | 28 | def test___new____yes(self): 29 | a = poor.Geocoder("digitransit") 30 | b = poor.Geocoder("digitransit") 31 | assert a is b 32 | 33 | def test_geocode__geo_uri(self): 34 | geocoder = poor.Geocoder("default") 35 | point = geocoder.geocode("geo:60.169,24.941") 36 | assert point[0]["x"] == 24.941 37 | assert point[0]["y"] == 60.169 38 | 39 | def test_geocode__lat_lon_comma(self): 40 | geocoder = poor.Geocoder("default") 41 | point = geocoder.geocode("60.169,24.941") 42 | assert point[0]["x"] == 24.941 43 | assert point[0]["y"] == 60.169 44 | 45 | def test_geocode__lat_lon_space(self): 46 | geocoder = poor.Geocoder("default") 47 | point = geocoder.geocode("60.169 24.941") 48 | assert point[0]["x"] == 24.941 49 | assert point[0]["y"] == 60.169 50 | -------------------------------------------------------------------------------- /poor/test/test_guide.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestGeocoder(poor.test.TestCase): 22 | 23 | def test___new____no(self): 24 | a = poor.Guide("foursquare") 25 | b = poor.Guide("nominatim") 26 | assert not a is b 27 | 28 | def test___new____yes(self): 29 | a = poor.Guide("foursquare") 30 | b = poor.Guide("foursquare") 31 | assert a is b 32 | -------------------------------------------------------------------------------- /poor/test/test_polysimp.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def test_simplify__max_length(self): 24 | x = [0, 1, 8] 25 | y = [0, 0, 0] 26 | xout, yout = poor.polysimp.simplify(x, y, tol=1, max_length=4) 27 | assert xout == [0, 4, 8] 28 | assert yout == [0, 0, 0] 29 | 30 | def test_simplify__nmax(self): 31 | x = [0, 1, 1, 2, 2] 32 | y = [0, 0, 1, 1, 2] 33 | xout, yout = poor.polysimp.simplify(x, y, tol=0.1, nmax=2) 34 | assert xout == [0, 2] 35 | assert yout == [0, 2] 36 | 37 | def test_simplify__no(self): 38 | x = [0, 1, 1, 2, 2] 39 | y = [0, 0, 1, 1, 2] 40 | xout, yout = poor.polysimp.simplify(x, y, tol=0.1) 41 | assert xout == x 42 | assert yout == y 43 | 44 | def test_simplify__yes(self): 45 | x = [0, 2, 4, 6, 8] 46 | y = [0, 1, 0, 1, 0] 47 | xout, yout = poor.polysimp.simplify(x, y, tol=1.1) 48 | assert xout == [0, 8] 49 | assert yout == [0, 0] 50 | -------------------------------------------------------------------------------- /poor/test/test_router.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestRouter(poor.test.TestCase): 22 | 23 | def test___new____no(self): 24 | a = poor.Router("mapquest_open") 25 | b = poor.Router("osrm") 26 | assert not a is b 27 | 28 | def test___new____yes(self): 29 | a = poor.Router("mapquest_open") 30 | b = poor.Router("mapquest_open") 31 | assert a is b 32 | -------------------------------------------------------------------------------- /poor/test/test_tilesource.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestConnectionPool(poor.test.TestCase): 22 | 23 | def test___new__(self): 24 | a = poor.TileSource("openstreetmap_@1x") 25 | b = poor.TileSource("hikebikemap_@1x") 26 | assert a._pool is b._pool 27 | 28 | 29 | class TestTileSource(poor.test.TestCase): 30 | 31 | def test___new____no(self): 32 | a = poor.TileSource("openstreetmap_@1x") 33 | b = poor.TileSource("hikebikemap_@1x") 34 | assert not a is b 35 | 36 | def test___new____yes(self): 37 | a = poor.TileSource("openstreetmap_@1x") 38 | b = poor.TileSource("openstreetmap_@1x") 39 | assert a is b 40 | -------------------------------------------------------------------------------- /poor/test/unittest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """Base class for unit test cases.""" 19 | 20 | __all__ = ("TestCase",) 21 | 22 | 23 | class TestCase: 24 | 25 | """Base class for unit test cases.""" 26 | 27 | def assert_raises(self, exception, function, *args, **kwargs): 28 | """Assert that calling `function` raises `exception`.""" 29 | try: 30 | function(*args, **kwargs) 31 | except exception: 32 | return 33 | raise AssertionError("{} failed to raise {}".format( 34 | repr(function), repr(exception))) 35 | 36 | def setUp(self): 37 | """Compatibility alias for :meth:`setup_method`.""" 38 | self.setup_method(None) 39 | 40 | def setup_method(self, method): 41 | """Set state for executing tests in `method`.""" 42 | pass 43 | 44 | def tearDown(self): 45 | """Compatibility alias for :meth:`teardown_method`.""" 46 | self.teardown_method(None) 47 | 48 | def teardown_method(self, method): 49 | """Remove state set for executing tests in `method`.""" 50 | pass 51 | 52 | def test___init__(self): 53 | """Make sure that :meth:`setup_method` is always run.""" 54 | pass 55 | -------------------------------------------------------------------------------- /qml/BubbleButton.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2015 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | 22 | Rectangle { 23 | id: button 24 | color: "#bbffffff" 25 | height: label.height + 1.5 * Theme.paddingMedium 26 | radius: Theme.paddingSmall 27 | width: label.width + 2.5 * Theme.paddingMedium 28 | 29 | property string text: "" 30 | 31 | // Use a pressed effect only when the associated action has 32 | // a delay, e.g. launching an external application. 33 | property bool useHighlight: false 34 | 35 | signal clicked() 36 | 37 | Label { 38 | id: label 39 | anchors.centerIn: parent 40 | color: "black" 41 | font.pixelSize: Theme.fontSizeExtraSmall 42 | text: button.text 43 | } 44 | 45 | MouseArea { 46 | anchors.fill: parent 47 | onClicked: { 48 | if (button.useHighlight) { 49 | button.color = Theme.highlightColor; 50 | timer.restart(); 51 | } 52 | button.clicked(); 53 | } 54 | } 55 | 56 | Timer { 57 | id: timer 58 | interval: 3000 59 | repeat: false 60 | onTriggered: button.color = "#bbffffff"; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /qml/BusyModal.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2015 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "." 22 | 23 | Item { 24 | id: busy 25 | anchors.fill: parent 26 | 27 | property string description: "" 28 | property string error: "" 29 | property bool running: false 30 | property string text: "" 31 | 32 | BusyIndicator { 33 | id: indicator 34 | anchors.centerIn: parent 35 | running: busy.running 36 | size: BusyIndicatorSize.Large 37 | visible: busy.running 38 | } 39 | 40 | Label { 41 | anchors.bottom: indicator.top 42 | anchors.bottomMargin: Math.round(indicator.height/4) 43 | color: Theme.highlightColor 44 | font.pixelSize: Theme.fontSizeLarge 45 | horizontalAlignment: Text.AlignHCenter 46 | text: busy.error || busy.text 47 | visible: busy.running || busy.error 48 | width: parent.width 49 | } 50 | 51 | ListItemLabel { 52 | anchors.top: indicator.bottom 53 | anchors.topMargin: Math.round(indicator.height/4) 54 | color: Theme.secondaryColor 55 | horizontalAlignment: Text.AlignHCenter 56 | text: busy.error ? "" : busy.description 57 | visible: busy.running 58 | wrapMode: Text.WordWrap 59 | } 60 | 61 | onErrorChanged: busy.error && (busy.text = ""); 62 | onTextChanged: busy.text && (busy.error = ""); 63 | 64 | } 65 | -------------------------------------------------------------------------------- /qml/Config.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | 21 | QtObject { 22 | 23 | function add(option, item) { 24 | // Add item to the value of option. 25 | return py.call_sync("poor.conf.add", [option, item]); 26 | } 27 | 28 | function contains(option, item) { 29 | // Return true if the value of option contains item. 30 | return py.call_sync("poor.conf.contains", [option, item]); 31 | } 32 | 33 | function get(option) { 34 | // Return the value of option. 35 | return py.call_sync("poor.conf.get", [option]); 36 | } 37 | 38 | function getDefault(option) { 39 | // Return default value of configuration option. 40 | return py.call_sync("poor.conf.get_default", [option]); 41 | } 42 | 43 | function remove(option, item) { 44 | // Remove item from the value of option. 45 | return py.call_sync("poor.conf.remove", [option, item]); 46 | } 47 | 48 | function set(option, value) { 49 | // Set the value of option. 50 | return py.call_sync("poor.conf.set", [option, value]); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /qml/CoverTile.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | 21 | Image { 22 | smooth: false 23 | } 24 | -------------------------------------------------------------------------------- /qml/IconListItem.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2016 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | 22 | ListItem { 23 | id: item 24 | anchors.left: parent.left 25 | anchors.right: parent.right 26 | contentHeight: Theme.itemSizeSmall 27 | 28 | property string icon: "" 29 | property string label: "" 30 | 31 | Image { 32 | id: icon 33 | anchors.left: parent.left 34 | anchors.leftMargin: Theme.horizontalPageMargin 35 | fillMode: Image.Pad 36 | height: Theme.itemSizeSmall 37 | source: item.icon 38 | } 39 | 40 | Label { 41 | id: label 42 | anchors.left: icon.right 43 | anchors.leftMargin: Theme.paddingMedium 44 | anchors.right: parent.right 45 | anchors.rightMargin: Theme.horizontalPageMargin 46 | color: item.highlighted ? Theme.highlightColor : Theme.primaryColor 47 | height: Theme.itemSizeSmall 48 | text: item.label 49 | truncationMode: TruncationMode.Fade 50 | verticalAlignment: Text.AlignVCenter 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /qml/ListItemLabel.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | 22 | Label { 23 | anchors.left: parent.left 24 | anchors.leftMargin: Theme.horizontalPageMargin 25 | anchors.right: parent.right 26 | anchors.rightMargin: Theme.horizontalPageMargin 27 | truncationMode: TruncationMode.Fade 28 | verticalAlignment: Text.AlignVCenter 29 | } 30 | -------------------------------------------------------------------------------- /qml/ManeuverMarker.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import QtLocation 5.0 21 | 22 | MapQuickItem { 23 | id: marker 24 | anchorPoint.x: sourceItem.width/2 25 | anchorPoint.y: sourceItem.height/2 26 | sourceItem: Image { 27 | smooth: true 28 | source: marker.passive ? 29 | app.getIcon("icons/node") : 30 | app.getIcon("icons/maneuver") 31 | } 32 | z: 201 33 | 34 | property real duration: 0 35 | property string icon: "flag" 36 | property string narrative: "" 37 | property bool passive: false 38 | property string verbalAlert: "" 39 | property string verbalPost: "" 40 | property string verbalPre: "" 41 | 42 | } 43 | -------------------------------------------------------------------------------- /qml/MapMouseArea.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2015 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import QtPositioning 5.3 21 | 22 | MouseArea { 23 | anchors.fill: parent 24 | onClicked: map.hidePoiBubbles(); 25 | onDoubleClicked: map.centerOnPosition(); 26 | onPressAndHold: { 27 | var coord = map.toCoordinate(Qt.point(mouse.x, mouse.y)); 28 | map.addPois([{ 29 | "x": coord.longitude, 30 | "y": coord.latitude, 31 | "title": app.tr("Unnamed point"), 32 | "text": app.tr("Unnamed point") 33 | }]); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /qml/MapPlugin.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import QtLocation 5.0 21 | 22 | /* 23 | * XXX: While waiting for QtLocation's Map component to support dynamic 24 | * custom tile sources, we need to use an existing map plugin to be able 25 | * to use the map canvas, pan, pinch-zoom, overlaid objects etc. 26 | * Luckily, we can use the Nokia plugin, but not load any Nokia tiles, 27 | * and overlay our own tiles as MapQuickItems. 28 | * 29 | * http://bugreports.qt.io/browse/QTBUG-32937 30 | * http://bugreports.qt.io/browse/QTBUG-36581 31 | * http://bugreports.qt.io/browse/QTBUG-40994 32 | * http://bugreports.qt.io/browse/QTBUG-43762 33 | */ 34 | 35 | Plugin { 36 | name: "here" 37 | parameters: [ 38 | PluginParameter { name: "app_id"; value: "N7qPce6rxX5gKujr6ia3"; }, 39 | PluginParameter { name: "app_code"; value: "4kEWsRWtJQpNFfQmpnknfA"; }, 40 | PluginParameter { name: "mapping.cache.directory"; value: "/dev/null"; }, 41 | PluginParameter { name: "mapping.host"; value: "127.0.0.1:65536"; } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /qml/MapTimer.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | 21 | Timer { 22 | interval: 500 23 | repeat: true 24 | running: app.running 25 | onTriggered: map.changed && map.updateTiles(); 26 | } 27 | -------------------------------------------------------------------------------- /qml/MenuButton.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "." 22 | 23 | IconButton { 24 | anchors.bottom: parent.bottom 25 | anchors.bottomMargin: Theme.paddingSmall 26 | anchors.horizontalCenter: parent.horizontalCenter 27 | height: icon.sourceSize.height 28 | icon.smooth: false 29 | icon.source: app.getIcon("icons/menu") 30 | visible: py.ready 31 | z: 600 32 | onClicked: app.showMenu(); 33 | } 34 | -------------------------------------------------------------------------------- /qml/NarrationTimer.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import QtPositioning 5.3 21 | 22 | Timer { 23 | id: timer 24 | interval: app.navigationActive ? 1000 : 3000 25 | repeat: true 26 | running: app.running && map.hasRoute 27 | triggeredOnStart: true 28 | 29 | property var coordPrev: QtPositioning.coordinate(0, 0) 30 | 31 | onRunningChanged: { 32 | // Always update after changing timer state. 33 | timer.coordPrev.longitude = 0; 34 | timer.coordPrev.latitude = 0; 35 | } 36 | 37 | onTriggered: { 38 | // Query maneuver narrative from Python and update status. 39 | if (!py.ready) return; 40 | var coord = map.position.coordinate; 41 | if (coord.distanceTo(timer.coordPrev) < 10) return; 42 | var accuracy = map.position.horizontalAccuracyValid ? 43 | map.position.horizontalAccuracy : null; 44 | var args = [coord.longitude, coord.latitude, accuracy, app.navigationActive]; 45 | py.call("poor.app.narrative.get_display", args, function(status) { 46 | app.updateNavigationStatus(status); 47 | timer.coordPrev.longitude = coord.longitude; 48 | timer.coordPrev.latitude = coord.latitude; 49 | }); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /qml/NorthArrow.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "." 22 | 23 | IconButton { 24 | anchors.bottom: parent.bottom 25 | anchors.bottomMargin: Theme.paddingSmall 26 | anchors.right: parent.right 27 | anchors.rightMargin: Theme.paddingSmall 28 | icon.rotation: map.rotation 29 | icon.smooth: true 30 | icon.source: app.getIcon("icons/north") 31 | z: 600 32 | 33 | onClicked: { 34 | if (map.autoRotate) { 35 | map.autoRotate = false; 36 | bubble.text = app.tr("Auto-rotate off"); 37 | } else { 38 | map.autoRotate = true; 39 | bubble.text = app.tr("Auto-rotate on"); 40 | } 41 | bubble.visible = true; 42 | timer.restart(); 43 | } 44 | 45 | Bubble { 46 | id: bubble 47 | anchorItem: parent 48 | showArrow: false 49 | state: "top-left" 50 | visible: false 51 | } 52 | 53 | Timer { 54 | id: timer 55 | interval: 2000 56 | repeat: false 57 | onTriggered: bubble.visible = false; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /qml/Notification.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2017 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "." 22 | 23 | Bubble { 24 | id: bubble 25 | anchorItem: app.navigationBlock 26 | anchors.topMargin: Theme.paddingLarge 27 | opacity: 0 28 | showArrow: false 29 | state: "bottom-center" 30 | visible: opacity > 0 31 | 32 | Behavior on opacity { FadeAnimator {} } 33 | 34 | Timer { 35 | id: timer 36 | interval: 5000 37 | repeat: false 38 | onTriggered: bubble.opacity = 0; 39 | } 40 | 41 | function clear(text) { 42 | bubble.opacity = 0; 43 | timer.stop(); 44 | } 45 | 46 | function flash(text) { 47 | bubble.text = text; 48 | bubble.opacity = 1; 49 | timer.restart(); 50 | } 51 | 52 | function hold(text) { 53 | bubble.text = text; 54 | bubble.opacity = 1; 55 | timer.stop(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /qml/Spacer.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2016 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | 21 | Rectangle { 22 | color: "#00000000" 23 | height: 0 24 | width: parent.width 25 | } 26 | -------------------------------------------------------------------------------- /qml/ToolItem.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2017 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | 22 | BackgroundItem { 23 | id: item 24 | height: image.height + label.height 25 | width: image.width 26 | 27 | property string icon: "" 28 | property string text: "" 29 | 30 | Image { 31 | id: image 32 | fillMode: Image.Pad 33 | height: sourceSize.height + Theme.paddingLarge + Theme.paddingMedium 34 | source: item.icon 35 | width: item.width 36 | } 37 | 38 | Label { 39 | id: label 40 | anchors.left: parent.left 41 | anchors.leftMargin: Theme.paddingSmall 42 | anchors.right: parent.right 43 | anchors.rightMargin: Theme.paddingSmall 44 | anchors.top: image.bottom 45 | color: item.highlighted ? Theme.highlightColor : Theme.primaryColor 46 | height: implicitHeight + Theme.paddingLarge 47 | horizontalAlignment: Text.AlignHCenter 48 | text: item.text 49 | wrapMode: Text.WordWrap 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /qml/icons/bubble-arrow@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/bubble-arrow@1.00.png -------------------------------------------------------------------------------- /qml/icons/bubble-arrow@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/bubble-arrow@1.25.png -------------------------------------------------------------------------------- /qml/icons/bubble-arrow@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/bubble-arrow@1.50.png -------------------------------------------------------------------------------- /qml/icons/bubble-arrow@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/bubble-arrow@1.75.png -------------------------------------------------------------------------------- /qml/icons/bubble-arrow@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/bubble-arrow@2.00.png -------------------------------------------------------------------------------- /qml/icons/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/cover.png -------------------------------------------------------------------------------- /qml/icons/maneuver@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/maneuver@1.00.png -------------------------------------------------------------------------------- /qml/icons/maneuver@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/maneuver@1.25.png -------------------------------------------------------------------------------- /qml/icons/maneuver@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/maneuver@1.50.png -------------------------------------------------------------------------------- /qml/icons/maneuver@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/maneuver@1.75.png -------------------------------------------------------------------------------- /qml/icons/maneuver@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/maneuver@2.00.png -------------------------------------------------------------------------------- /qml/icons/menu@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/menu@1.00.png -------------------------------------------------------------------------------- /qml/icons/menu@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/menu@1.25.png -------------------------------------------------------------------------------- /qml/icons/menu@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/menu@1.50.png -------------------------------------------------------------------------------- /qml/icons/menu@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/menu@1.75.png -------------------------------------------------------------------------------- /qml/icons/menu@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/menu@2.00.png -------------------------------------------------------------------------------- /qml/icons/navigation/README.md: -------------------------------------------------------------------------------- 1 | Navigation icons are borrowed from Mapbox's [directions-icons][1], 2 | available under the CC0 license. Icons are used as-is except for simple 3 | renaming and color-inversion. 4 | 5 | ```bash 6 | rename "s/_/-/g" *.svg 7 | sed -i "s/#000000/#ffffff/g" *.svg 8 | ``` 9 | 10 | The ferry icon is borrowed from Mapbox's [Maki Icon Set][2], available 11 | under the CC0 license. 12 | 13 | [1]: https://github.com/mapbox/directions-icons 14 | [2]: https://github.com/mapbox/maki 15 | -------------------------------------------------------------------------------- /qml/icons/navigation/arrive-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/arrive-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/arrive-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/arrive.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/close.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue-uturn.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/continue.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/depart-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/depart-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/depart-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/depart.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/end-of-road-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/end-of-road-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/fork.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid-uturn.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/invalid.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/merge-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/merge-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/merge-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/merge-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/merge-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/new-name-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notificaiton-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/notification-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/off-ramp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/off-ramp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/off-ramp-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/off-ramp-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/on-ramp-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/rotary.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/roundabout.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-sharp-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-sharp-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-slight-left.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-slight-right.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/turn-straight.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/updown.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/navigation/uturn.svg: -------------------------------------------------------------------------------- 1 | 2 | direction 3 | 4 | 5 | -------------------------------------------------------------------------------- /qml/icons/node@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/node@1.00.png -------------------------------------------------------------------------------- /qml/icons/node@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/node@1.25.png -------------------------------------------------------------------------------- /qml/icons/node@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/node@1.50.png -------------------------------------------------------------------------------- /qml/icons/node@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/node@1.75.png -------------------------------------------------------------------------------- /qml/icons/node@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/node@2.00.png -------------------------------------------------------------------------------- /qml/icons/north@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/north@1.00.png -------------------------------------------------------------------------------- /qml/icons/north@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/north@1.25.png -------------------------------------------------------------------------------- /qml/icons/north@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/north@1.50.png -------------------------------------------------------------------------------- /qml/icons/north@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/north@1.75.png -------------------------------------------------------------------------------- /qml/icons/north@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/north@2.00.png -------------------------------------------------------------------------------- /qml/icons/poi@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/poi@1.00.png -------------------------------------------------------------------------------- /qml/icons/poi@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/poi@1.25.png -------------------------------------------------------------------------------- /qml/icons/poi@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/poi@1.50.png -------------------------------------------------------------------------------- /qml/icons/poi@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/poi@1.75.png -------------------------------------------------------------------------------- /qml/icons/poi@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/poi@2.00.png -------------------------------------------------------------------------------- /qml/icons/position-direction@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position-direction@1.00.png -------------------------------------------------------------------------------- /qml/icons/position-direction@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position-direction@1.25.png -------------------------------------------------------------------------------- /qml/icons/position-direction@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position-direction@1.50.png -------------------------------------------------------------------------------- /qml/icons/position-direction@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position-direction@1.75.png -------------------------------------------------------------------------------- /qml/icons/position-direction@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position-direction@2.00.png -------------------------------------------------------------------------------- /qml/icons/position@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position@1.00.png -------------------------------------------------------------------------------- /qml/icons/position@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position@1.25.png -------------------------------------------------------------------------------- /qml/icons/position@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position@1.50.png -------------------------------------------------------------------------------- /qml/icons/position@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position@1.75.png -------------------------------------------------------------------------------- /qml/icons/position@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/position@2.00.png -------------------------------------------------------------------------------- /qml/icons/svg2png: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob, os, xml.dom.minidom 3 | for svg in glob.glob("*.svg"): 4 | # Skip icons used as a single size. 5 | if os.path.isfile(svg.replace("svg", "png")): continue 6 | doc = xml.dom.minidom.parse(svg) 7 | doc = doc.getElementsByTagName("svg")[0] 8 | width = int(doc.getAttribute("width")) 9 | height = int(doc.getAttribute("height")) 10 | assert width > 0 and height > 0 11 | for ratio in [1.00, 1.25, 1.50, 1.75, 2.00]: 12 | png = "{}@{:.2f}.png".format(svg[:-4], ratio) 13 | os.system("inkscape -f {} -e {} -C -w {:.0f} -h {:.0f}" 14 | .format(svg, png, ratio*width, ratio*height)) 15 | -------------------------------------------------------------------------------- /qml/icons/tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/qml/icons/tile.png -------------------------------------------------------------------------------- /routers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/__init__.py -------------------------------------------------------------------------------- /routers/digitransit.graphql: -------------------------------------------------------------------------------- 1 | { 2 | plan( 3 | arriveBy: {arrive_by} 4 | date: "{date}" 5 | from: {fm} 6 | modes: "{modes}" 7 | numItineraries: 5 8 | time: "{time}" 9 | to: {to} 10 | transferPenalty: {transfer_penalty} 11 | walkReluctance: {walk_reluctance} 12 | ) { 13 | itineraries { 14 | duration 15 | legs { 16 | distance 17 | duration 18 | endTime 19 | from { 20 | lat 21 | lon 22 | name 23 | } 24 | intermediateStops { 25 | lat 26 | lon 27 | name 28 | } 29 | legGeometry { 30 | points 31 | } 32 | mode 33 | realTime 34 | route { 35 | agency { 36 | name 37 | } 38 | desc 39 | longName 40 | shortName 41 | } 42 | startTime 43 | to { 44 | lat 45 | lon 46 | name 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /routers/digitransit.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © HSL, Liikennevirasto", 3 | "_description": "Public transport routing in Finland", 4 | "_modes": ["public transport"], 5 | "name": "Digitransit", 6 | "source": "digitransit.fi" 7 | } 8 | -------------------------------------------------------------------------------- /routers/digitransit/README.md: -------------------------------------------------------------------------------- 1 | Source: 2 | -------------------------------------------------------------------------------- /routers/digitransit/airplane.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 30 | -------------------------------------------------------------------------------- /routers/digitransit/airplane@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/airplane@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/airplane@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/airplane@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/airplane@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/airplane@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/airplane@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/airplane@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/airplane@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/airplane@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/bus@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/bus@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/bus@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/bus@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/bus@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/bus@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/bus@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/bus@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/bus@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/bus@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/citybike@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/citybike@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/citybike@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/citybike@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/citybike@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/citybike@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/citybike@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/citybike@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/citybike@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/citybike@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/ferry@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/ferry@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/ferry@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/ferry@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/ferry@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/ferry@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/ferry@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/ferry@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/ferry@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/ferry@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/metro@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/metro@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/metro@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/metro@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/metro@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/metro@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/metro@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/metro@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/metro@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/metro@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/svg2png: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import glob, os 3 | for svg in glob.glob("*.svg"): 4 | width, height = 86, 86 5 | for ratio in [1.00, 1.25, 1.50, 1.75, 2.00]: 6 | png = "{}@{:.2f}.png".format(svg[:-4], ratio) 7 | os.system("inkscape -f {} -e {} -C -w {:.0f} -h {:.0f}" 8 | .format(svg, png, ratio*width, ratio*height)) 9 | -------------------------------------------------------------------------------- /routers/digitransit/train@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/train@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/train@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/train@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/train@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/train@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/train@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/train@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/train@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/train@2.00.png -------------------------------------------------------------------------------- /routers/digitransit/tram@1.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/tram@1.00.png -------------------------------------------------------------------------------- /routers/digitransit/tram@1.25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/tram@1.25.png -------------------------------------------------------------------------------- /routers/digitransit/tram@1.50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/tram@1.50.png -------------------------------------------------------------------------------- /routers/digitransit/tram@1.75.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/tram@1.75.png -------------------------------------------------------------------------------- /routers/digitransit/tram@2.00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/digitransit/tram@2.00.png -------------------------------------------------------------------------------- /routers/mapquest_open.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Routing based on OpenStreetMap data", 4 | "_modes": ["car", "bicycle", "foot"], 5 | "name": "MapQuest Open", 6 | "source": "open.mapquest.com" 7 | } 8 | -------------------------------------------------------------------------------- /routers/mapquest_open_results.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "../qml" 22 | 23 | Page { 24 | id: page 25 | allowedOrientations: app.defaultAllowedOrientations 26 | 27 | property bool loading: true 28 | 29 | BusyModal { 30 | id: busy 31 | running: page.loading 32 | } 33 | 34 | onStatusChanged: { 35 | if (page.status === PageStatus.Activating) { 36 | busy.text = app.tr("Searching"); 37 | } else if (page.status === PageStatus.Active) { 38 | page.findRoute(); 39 | } 40 | } 41 | 42 | function findRoute() { 43 | // Load routing results from the Python backend. 44 | var routePage = app.pageStack.previousPage(); 45 | var args = [routePage.from, routePage.to]; 46 | py.call("poor.app.router.route", args, function(route) { 47 | if (route && route.error && route.message) { 48 | busy.error = route.message; 49 | page.loading = false; 50 | } else if (route && route.x && route.x.length > 0) { 51 | app.hideMenu(); 52 | map.addRoute(route); 53 | map.hidePoiBubbles(); 54 | map.fitViewToRoute(); 55 | map.addManeuvers(route.maneuvers); 56 | app.pageStack.navigateBack(PageStackAction.Immediate); 57 | } else { 58 | busy.error = app.tr("No results"); 59 | page.loading = false; 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /routers/osmscout.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Routing based on OpenStreetMap data", 4 | "_modes": ["car", "bicycle", "foot"], 5 | "name": "OSM Scout", 6 | "offline": true, 7 | "requires": ["harbour-osmscout-server", "harbour-osmscout-server-module-route"], 8 | "_source": "OSM Scout offline server" 9 | } 10 | -------------------------------------------------------------------------------- /routers/osmscout_results.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "../qml" 22 | 23 | Page { 24 | id: page 25 | allowedOrientations: app.defaultAllowedOrientations 26 | 27 | property bool loading: true 28 | 29 | BusyModal { 30 | id: busy 31 | running: page.loading 32 | } 33 | 34 | onStatusChanged: { 35 | if (page.status === PageStatus.Activating) { 36 | busy.text = app.tr("Searching"); 37 | } else if (page.status === PageStatus.Active) { 38 | page.findRoute(); 39 | } 40 | } 41 | 42 | function findRoute() { 43 | // Load routing results from the Python backend. 44 | var routePage = app.pageStack.previousPage(); 45 | var args = [routePage.from, routePage.to]; 46 | py.call("poor.app.router.route", args, function(route) { 47 | if (route && route.error && route.message) { 48 | busy.error = route.message; 49 | page.loading = false; 50 | } else if (route && route.x && route.x.length > 0) { 51 | app.hideMenu(); 52 | map.addRoute(route); 53 | map.hidePoiBubbles(); 54 | map.fitViewToRoute(); 55 | map.addManeuvers(route.maneuvers); 56 | app.pageStack.navigateBack(PageStackAction.Immediate); 57 | } else { 58 | busy.error = app.tr("No results"); 59 | page.loading = false; 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /routers/osrm.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "_description": "Routing based on OpenStreetMap data", 4 | "_modes": ["car"], 5 | "name": "OSRM", 6 | "source": "project-osrm.org" 7 | } 8 | -------------------------------------------------------------------------------- /routers/osrm_results.qml: -------------------------------------------------------------------------------- 1 | /* -*- coding: utf-8-unix -*- 2 | * 3 | * Copyright (C) 2014 Osmo Salomaa 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 2.0 20 | import Sailfish.Silica 1.0 21 | import "../qml" 22 | 23 | Page { 24 | id: page 25 | allowedOrientations: app.defaultAllowedOrientations 26 | 27 | property bool loading: true 28 | 29 | BusyModal { 30 | id: busy 31 | running: page.loading 32 | } 33 | 34 | onStatusChanged: { 35 | if (page.status === PageStatus.Activating) { 36 | busy.text = app.tr("Searching"); 37 | } else if (page.status === PageStatus.Active) { 38 | page.findRoute(); 39 | } 40 | } 41 | 42 | function findRoute() { 43 | // Load routing results from the Python backend. 44 | var routePage = app.pageStack.previousPage(); 45 | var args = [routePage.from, routePage.to]; 46 | py.call("poor.app.router.route", args, function(route) { 47 | if (route && route.error && route.message) { 48 | busy.error = route.message; 49 | page.loading = false; 50 | } else if (route && route.x && route.x.length > 0) { 51 | app.hideMenu(); 52 | map.addRoute(route); 53 | map.hidePoiBubbles(); 54 | map.fitViewToRoute(); 55 | map.addManeuvers(route.maneuvers); 56 | app.pageStack.navigateBack(PageStackAction.Immediate); 57 | } else { 58 | busy.error = app.tr("No results"); 59 | page.loading = false; 60 | } 61 | }); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /routers/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/routers/test/__init__.py -------------------------------------------------------------------------------- /routers/test/test_digitransit.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.router = poor.Router("digitransit") 25 | 26 | def test_geocode(self): 27 | results = self.router.route("munkkiniemi, helsinki", "kumpula, helsinki") 28 | results = list(map(poor.AttrDict, results)) 29 | assert results 30 | for result in results: 31 | assert result.maneuvers 32 | assert result.x 33 | assert result.y 34 | -------------------------------------------------------------------------------- /routers/test/test_mapquest_open.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.router = poor.Router("mapquest_open") 25 | 26 | def test_geocode(self): 27 | result = self.router.route("viikki, helsinki", "kontula, helsinki") 28 | result = poor.AttrDict(result) 29 | assert result.maneuvers 30 | assert result.x 31 | assert result.y 32 | -------------------------------------------------------------------------------- /routers/test/test_osrm.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import poor.test 19 | 20 | 21 | class TestModule(poor.test.TestCase): 22 | 23 | def setup_method(self, method): 24 | self.router = poor.Router("osrm") 25 | 26 | # XXX: OSRM demo server is often over capacity. 27 | def __test_geocode(self): 28 | result = self.router.route("maunula, helsinki", "kallio, helsinki") 29 | result = poor.AttrDict(result) 30 | assert result.maneuvers 31 | assert result.x 32 | assert result.y 33 | -------------------------------------------------------------------------------- /rpm/harbour-poor-maps.spec: -------------------------------------------------------------------------------- 1 | # Prevent brp-python-bytecompile from running. 2 | %define __os_install_post %{___build_post} 3 | 4 | # "Harbour RPM packages should not provide anything." 5 | %define __provides_exclude_from ^%{_datadir}/.*$ 6 | 7 | Name: harbour-poor-maps 8 | Version: 0.34.3 9 | Release: 1 10 | Summary: Maps and navigation 11 | License: GPLv3+ 12 | URL: https://github.com/otsaloma/poor-maps 13 | Source: %{name}-%{version}.tar.xz 14 | BuildArch: noarch 15 | BuildRequires: gettext 16 | BuildRequires: make 17 | BuildRequires: qt5-qttools-linguist 18 | Requires: libkeepalive 19 | Requires: libsailfishapp-launcher 20 | Requires: pyotherside-qml-plugin-python3-qt5 >= 1.2 21 | Requires: qt5-plugin-geoservices-here 22 | Requires: qt5-qtdeclarative-import-location 23 | Requires: qt5-qtdeclarative-import-multimedia >= 5.2 24 | Requires: qt5-qtdeclarative-import-positioning >= 5.2 25 | Requires: sailfishsilica-qt5 26 | 27 | %description 28 | View maps, find places and routes, navigate with turn-by-turn instructions, 29 | search for nearby places by type and share your location. 30 | 31 | %prep 32 | %setup -q 33 | 34 | %install 35 | make DESTDIR=%{buildroot} PREFIX=/usr install 36 | 37 | %files 38 | %defattr(-,root,root,-) 39 | %{_datadir}/%{name} 40 | %{_datadir}/applications/%{name}.desktop 41 | %{_datadir}/icons/hicolor/*/apps/%{name}.png 42 | -------------------------------------------------------------------------------- /tilesources/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/tilesources/__init__.py -------------------------------------------------------------------------------- /tilesources/aster_gdem_srtm_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "GIScience Research Group @ Heidelberg University\nData © CIAT, METI, NASA, NOAA", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "ASTER GDEM & SRTM Hillshade @1x", 6 | "scale": 1, 7 | "source": "giscience.uni-hd.de", 8 | "type": "overlay", 9 | "url": "http://korona.geog.uni-heidelberg.de/tiles/asterh/x={x}&y={y}&z={z}", 10 | "z": 10 11 | } 12 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets @1x", 6 | "scale": 1, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets/{z}/{x}/{y}.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets @2x", 6 | "scale": 2, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets/{z}/{x}/{y}@2x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_@3x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets @3x", 6 | "scale": 3, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets/{z}/{x}/{y}@3x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_@4x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets @4x", 6 | "scale": 4, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets/{z}/{x}/{y}@4x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_english_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets English @1x", 6 | "scale": 1, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets-english/{z}/{x}/{y}.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_english_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets English @2x", 6 | "scale": 2, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets-english/{z}/{x}/{y}@2x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_english_@3x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets English @3x", 6 | "scale": 3, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets-english/{z}/{x}/{y}@3x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/cartago_streets_english_@4x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Osmo Salomaa © OpenMapTiles © OpenStreetMap", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Cartago Streets English @4x", 6 | "scale": 4, 7 | "source": "cartago.io", 8 | "url": "http://tile.cartago.io/styles/cartago-streets-english/{z}/{x}/{y}@4x.png?apikey=60a99f2yarnuahk3" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/hikebikemap_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors\nHillshading: SRTM3 v2 (NASA)", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Hike & Bike Map @1x", 6 | "scale": 1, 7 | "source": "hikebikemap.org", 8 | "url": "http://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/hsl_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "HSL @1x", 6 | "scale": 2, 7 | "source": "digitransit.fi", 8 | "url": "http://api.digitransit.fi/map/v1/hsl-map/{z}/{x}/{y}.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/hsl_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "HSL @2x", 6 | "scale": 4, 7 | "source": "digitransit.fi", 8 | "url": "http://api.digitransit.fi/map/v1/hsl-map/{z}/{x}/{y}@2x.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_outdoors_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Outdoors @1x", 6 | "scale": 1, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/v4/mapbox.outdoors/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_outdoors_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Outdoors @2x", 6 | "scale": 2, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/v4/mapbox.outdoors/{z}/{x}/{y}@2x.png?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_outdoors_gl_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Outdoors GL @1x", 6 | "scale": 2, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/styles/v1/otsaloma/cioge9c5m0004cqno072gh0bh/tiles/{z}/{x}/{y}?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_outdoors_gl_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Outdoors GL @2x", 6 | "scale": 4, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/styles/v1/otsaloma/cioge9c5m0004cqno072gh0bh/tiles/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_streets_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Streets @1x", 6 | "scale": 1, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/v4/mapbox.streets-basic/{z}/{x}/{y}.png?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_streets_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Streets @2x", 6 | "scale": 2, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/v4/mapbox.streets-basic/{z}/{x}/{y}@2x.png?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_streets_gl_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Streets GL @1x", 6 | "scale": 2, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/styles/v1/otsaloma/ciogdk8zp0006dani2i3b96vv/tiles/{z}/{x}/{y}?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/mapbox_streets_gl_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© Mapbox © OpenStreetMap\nhttps://www.mapbox.com/about/maps/\nhttps://www.mapbox.com/map-feedback/", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Mapbox Streets GL @2x", 6 | "scale": 4, 7 | "source": "mapbox.com", 8 | "url": "https://api.mapbox.com/styles/v1/otsaloma/ciogdk8zp0006dani2i3b96vv/tiles/{z}/{x}/{y}@2x?access_token=pk.eyJ1Ijoib3RzYWxvbWEiLCJhIjoiNW5MOTN6YyJ9.RnPbZEzAX5z8V0DjqycyMQ" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/opencyclemap_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Thunderforest\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "OpenCycleMap @1x", 6 | "scale": 1, 7 | "source": "thunderforest.com", 8 | "url": "https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=0890777c70cf4966a624a99e258ef9a8" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/opencyclemap_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Thunderforest\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "OpenCycleMap @2x", 6 | "scale": 2, 7 | "source": "thunderforest.com", 8 | "url": "https://tile.thunderforest.com/cycle/{z}/{x}/{y}@2x.png?apikey=0890777c70cf4966a624a99e258ef9a8" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/openseamap_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "OpenSeaMap @1x", 6 | "scale": 1, 7 | "source": "openseamap.org", 8 | "type": "overlay", 9 | "url": "http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png", 10 | "z": 30 11 | } 12 | -------------------------------------------------------------------------------- /tilesources/openstreetmap_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "© OpenStreetMap contributors\nhttp://www.openstreetmap.org/copyright", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "OpenStreetMap @1x", 6 | "scale": 1, 7 | "source": "openstreetmap.org", 8 | "url": "http://tile.openstreetmap.org/{z}/{x}/{y}.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/opnvkarte_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © MeMoMaps\nData© OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "ÖPNVKarte @1x", 6 | "scale": 1, 7 | "source": "öpnvkarte.de", 8 | "url": "http://tileserver.memomaps.de/tilegen/{z}/{x}/{y}.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/osmscout_car_day_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout car day @1x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 2, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?style=car&daylight=1&shift=1&scale=2&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_car_day_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout car day @2x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 4, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?style=car&daylight=1&shift=1&scale=4&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_car_night_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout car night @1x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 2, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?style=car&daylight=0&shift=1&scale=2&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_car_night_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout car night @2x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 4, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?style=car&daylight=0&shift=1&scale=4&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_day_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout day @1x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 2, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?daylight=1&shift=1&scale=2&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_day_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout day @2x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 4, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?daylight=1&shift=1&scale=4&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_night_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout night @1x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 2, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?daylight=0&shift=1&scale=2&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/osmscout_night_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Data © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "_name": "OSM Scout night @2x", 6 | "requires": ["harbour-osmscout-server"], 7 | "scale": 4, 8 | "_source": "OSM Scout offline server", 9 | "url": "http://localhost:8553/v1/tile?daylight=0&shift=1&scale=4&z={z}&x={x}&y={y}" 10 | } 11 | -------------------------------------------------------------------------------- /tilesources/quadkey.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | """ 19 | A variation of the 'slippy' format using quadtree key indexing. 20 | 21 | This tile format is used at least by Bing. The tile division is equivalent 22 | to the 'slippy' format, but tiles are referred to using a single key 23 | constructed from the usual X, Y and Z values. 24 | 25 | http://msdn.microsoft.com/en-us/library/bb259689.aspx 26 | """ 27 | 28 | import importlib.machinery 29 | import os 30 | 31 | path = os.path.join(os.path.dirname(__file__), "slippy.py") 32 | loader = importlib.machinery.SourceFileLoader("slippy", path) 33 | slippy = loader.load_module("slippy") 34 | tile_corners = slippy.tile_corners 35 | tile_path = slippy.tile_path 36 | 37 | def list_tiles(xmin, xmax, ymin, ymax, zoom): 38 | """Return a sequence of tiles within given bounding box.""" 39 | tiles = slippy.list_tiles(xmin, xmax, ymin, ymax, zoom) 40 | for tile in tiles: 41 | tile["key"] = num2key(tile["x"], tile["y"], tile["z"]) 42 | return tiles 43 | 44 | def num2key(xtile, ytile, zoom): 45 | """Convert tile numbers to quadkey.""" 46 | key = "" 47 | for bit in reversed(range(1, zoom+1)): 48 | digit = ord("0") 49 | mask = 1 << (bit - 1) 50 | if xtile & mask != 0: 51 | digit += 1 52 | if ytile & mask != 0: 53 | digit += 2 54 | key += chr(digit) 55 | return key 56 | -------------------------------------------------------------------------------- /tilesources/sputnik_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Sputnik\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Sputnik @1x", 6 | "scale": 1, 7 | "source": "maps.sputnik.ru", 8 | "url": "http://tiles.maps.sputnik.ru/{z}/{x}/{y}.png" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/sputnik_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Sputnik\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Sputnik @2x", 6 | "scale": 2, 7 | "source": "maps.sputnik.ru", 8 | "url": "http://tiles.maps.sputnik.ru/{z}/{x}/{y}.png?tag=retina" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/otsaloma/poor-maps/007e16dafec0d15fe78917b0e4bc3e71abb146a5/tilesources/test/__init__.py -------------------------------------------------------------------------------- /tilesources/test/test_quadkey.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import importlib.machinery 19 | import os 20 | import poor.test 21 | 22 | 23 | class TestModule(poor.test.TestCase): 24 | 25 | def setup_method(self, method): 26 | path = os.path.join(os.path.dirname(__file__), "..", "quadkey.py") 27 | loader = importlib.machinery.SourceFileLoader("format", path) 28 | self.format = loader.load_module("format") 29 | 30 | def test_num2key(self): 31 | key = self.format.num2key(149233, 75880, 18) 32 | assert key == "120120211013312001" 33 | -------------------------------------------------------------------------------- /tilesources/test/test_slippy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import importlib.machinery 19 | import os 20 | import poor.test 21 | 22 | 23 | class TestModule(poor.test.TestCase): 24 | 25 | def setup_method(self, method): 26 | path = os.path.join(os.path.dirname(__file__), "..", "slippy.py") 27 | loader = importlib.machinery.SourceFileLoader("format", path) 28 | self.format = loader.load_module("format") 29 | 30 | def test_deg2num(self): 31 | xtile, ytile = self.format.deg2num(24.94093, 60.16867, 18) 32 | assert xtile == 149233 33 | assert ytile == 75880 34 | 35 | def test_num2deg(self): 36 | x, y = self.format.num2deg(149233, 75880, 18) 37 | assert abs(x - 24.94034) < 0.00001 38 | assert abs(y - 60.16884) < 0.00001 39 | -------------------------------------------------------------------------------- /tilesources/test/test_slippy_elliptical.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2014 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import importlib.machinery 19 | import os 20 | import poor.test 21 | 22 | 23 | class TestModule(poor.test.TestCase): 24 | 25 | def setup_method(self, method): 26 | path = os.path.join(os.path.dirname(__file__), "..", "slippy_elliptical.py") 27 | loader = importlib.machinery.SourceFileLoader("format", path) 28 | self.format = loader.load_module("format") 29 | 30 | def test_deg2num(self): 31 | xtile, ytile = self.format.deg2num(24.94093, 60.16867, 18) 32 | assert xtile == 149233 33 | assert ytile == 76122 34 | 35 | def test_num2deg(self): 36 | x, y = self.format.num2deg(149233, 76122, 18) 37 | assert abs(x - 24.94034) < 0.00001 38 | assert abs(y - 60.16932) < 0.00001 39 | -------------------------------------------------------------------------------- /tilesources/test/test_urls.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright (C) 2015 Osmo Salomaa 4 | # 5 | # This program is free software: you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation, either version 3 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program. If not, see . 17 | 18 | import imghdr 19 | import os 20 | import poor.test 21 | import random 22 | 23 | 24 | class TestModule(poor.test.TestCase): 25 | 26 | # XXX: Only test the default basemap tile source? Some of the other 27 | # tile sources tend to be broken for a short while every now and then, 28 | # which is probably not something we would need to react to. 29 | 30 | def get(self, name): 31 | directory = os.path.join(os.path.dirname(__file__), "..") 32 | path = os.path.join(directory, "{}.json".format(name)) 33 | tilesource = poor.util.read_json(path) 34 | url = tilesource["url"].format( 35 | x=random.randint(2071, 2080), 36 | y=random.randint(1401, 1410), 37 | z=12) 38 | 39 | blob = poor.http.get(url) 40 | imgtype = imghdr.what("", h=blob) 41 | assert imgtype in ("jpeg", "png") 42 | 43 | def test_mapbox_streets_gl(self): 44 | self.get("mapbox_streets_gl_@1x") 45 | self.get("mapbox_streets_gl_@2x") 46 | -------------------------------------------------------------------------------- /tilesources/thunderforest_transport_@1x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Thunderforest\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Thunderforest Transport @1x", 6 | "scale": 1, 7 | "source": "thunderforest.com", 8 | "url": "https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=0890777c70cf4966a624a99e258ef9a8" 9 | } 10 | -------------------------------------------------------------------------------- /tilesources/thunderforest_transport_@2x.json: -------------------------------------------------------------------------------- 1 | { 2 | "attribution": "Maps © Thunderforest\nData © OpenStreetMap contributors", 3 | "extension": ".png", 4 | "format": "slippy", 5 | "name": "Thunderforest Transport @2x", 6 | "scale": 2, 7 | "source": "thunderforest.com", 8 | "url": "https://tile.thunderforest.com/transport/{z}/{x}/{y}@2x.png?apikey=0890777c70cf4966a624a99e258ef9a8" 9 | } 10 | -------------------------------------------------------------------------------- /tools/check-translations: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Check translation files for common errors. 5 | Usage: check-translations [XX[_YY[@ZZ]]...] 6 | """ 7 | import glob, polib, re, sys 8 | def print_error(title, entry): 9 | print("\n{}:".format(title), entry, sep="\n") 10 | FLAGS = re.MULTILINE 11 | args = list("po/{}.po".format(x) for x in sys.argv[1:]) 12 | for name in args or sorted(glob.glob("po/*.po")): 13 | po = polib.pofile(name) 14 | print("{}: {}% translated".format(name, po.percent_translated())) 15 | for entry in po.translated_entries(): 16 | # Check that Python string formatting fields exists as-is 17 | # in the translation (order can vary, but not the field). 18 | for field in re.findall(r"\{.*?\}", entry.msgid, flags=FLAGS): 19 | if not field in entry.msgstr: 20 | print_error("Python string formatting mismatch", entry) 21 | raise SystemExit("FATAL ERROR") 22 | # Check that QML string formatting fields exists as-is 23 | # in the translation (order can vary, but not the field). 24 | for field in re.findall(r"%\d+", entry.msgid, flags=FLAGS): 25 | if not field in entry.msgstr: 26 | print_error("QML string formatting mismatch", entry) 27 | raise SystemExit("FATAL ERROR") 28 | -------------------------------------------------------------------------------- /tools/release: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Commit changes, tag and push release to GitHub. 3 | cd "$(dirname "$0")/.." || exit 1 4 | VERSION="$(python3 -c "import poor; print(poor.__version__)")" 5 | echo "Git status:" 6 | git status --porcelain 7 | printf "\nRelease version: $VERSION\n" 8 | read -p "Press Enter to continue or Ctrl+C to abort: " 9 | git commit -a -m "RELEASE $VERSION" 10 | git tag -s -m "RELEASE $VERSION" $VERSION 11 | git push 12 | git push --tags 13 | echo "" 14 | echo "Add release notes and possible downloads:" 15 | echo "https://github.com/otsaloma/poor-maps/tags" 16 | echo "" 17 | egrep -B 999 -m2 "==+" NEWS.md 18 | -------------------------------------------------------------------------------- /tools/update-translations: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "$(dirname "$0")/.." || exit 1 3 | truncate -s0 po/poor-maps.pot 4 | # Python code 5 | xgettext --output=po/poor-maps.pot \ 6 | --join-existing \ 7 | --from-code=UTF-8 \ 8 | --language=Python \ 9 | --keyword=_:1 \ 10 | --keyword=__:1 \ 11 | --add-comments=TRANSLATORS: \ 12 | */*.py 13 | 14 | # QML and JavaScript code 15 | xgettext --output=po/poor-maps.pot \ 16 | --join-existing \ 17 | --from-code=UTF-8 \ 18 | --language=JavaScript \ 19 | --keyword=tr:1 \ 20 | --keyword=qsTranslate:2 \ 21 | --add-comments=TRANSLATORS: \ 22 | */*.qml qml/js/*.js 23 | 24 | # JSON metadata 25 | cat */*.json \ 26 | | grep '^ *"_' \ 27 | | sed 's/: *\("[^"]*"\)/: _(\1)/' \ 28 | | sed 's/\("[^"]*"\)\(,\|]\)/_(\1)\2/g' \ 29 | | xgettext --output=po/poor-maps.pot \ 30 | --join-existing \ 31 | --from-code=UTF-8 \ 32 | --language=JavaScript \ 33 | --keyword=_:1 \ 34 | - 35 | --------------------------------------------------------------------------------