aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJochen Topf <jochen@topf.org>2014-08-21 14:38:23 +0200
committerJochen Topf <jochen@topf.org>2014-08-21 14:38:23 +0200
commit960a39f5937a50b4d999a3fc5e7465412eb377a0 (patch)
treeafd6af6c77f8f30e862ed80c3f2b3279d577e9f0
parentcd12010108e17dfab6ebf6f2902663430505bcfe (diff)
downloadtaginfo-960a39f5937a50b4d999a3fc5e7465412eb377a0.tar
taginfo-960a39f5937a50b4d999a3fc5e7465412eb377a0.tar.gz
Add new 'projects' source.
Any kind of project using OSM tags can create a json-formatted taginfo project file and after its URL is added to the taginfo config, taginfo will integrate this data into its database.
-rw-r--r--projects/README2
-rw-r--r--projects/id_editor.json484
-rw-r--r--projects/id_editor.pngbin0 -> 458 bytes
-rw-r--r--projects/osrm.json41
-rw-r--r--projects/osrm.pngbin0 -> 909 bytes
-rwxr-xr-xsources/projects/import.rb69
-rwxr-xr-xsources/projects/parse.rb85
-rw-r--r--sources/projects/post.sql15
-rw-r--r--sources/projects/pre.sql46
-rw-r--r--sources/projects/project_list.txt4
-rwxr-xr-xsources/projects/update.sh48
-rw-r--r--web/i18n/de.yml21
-rw-r--r--web/i18n/en.yml21
-rw-r--r--web/lib/api/v4/project.rb66
-rw-r--r--web/lib/api/v4/projects.rb53
-rw-r--r--web/lib/api/v4/tag.rb63
-rw-r--r--web/lib/projects.rb51
-rw-r--r--web/lib/ui/projects.rb31
-rw-r--r--web/lib/ui/taginfo.rb7
-rw-r--r--web/public/css/taginfo.css5
-rw-r--r--web/public/img/sources/projects.16.pngbin0 -> 951 bytes
-rw-r--r--web/public/img/sources/projects.24.pngbin0 -> 1309 bytes
-rw-r--r--web/public/img/sources/projects.32.pngbin0 -> 2658 bytes
-rw-r--r--web/public/img/sources/projects.48.pngbin0 -> 4733 bytes
-rw-r--r--web/public/js/taginfo.js38
-rwxr-xr-xweb/taginfo.rb5
-rw-r--r--web/views/key.erb6
-rw-r--r--web/views/project.erb46
-rw-r--r--web/views/projects.erb8
-rw-r--r--web/views/tag.erb6
-rw-r--r--web/views/taginfo/index.erb1
-rw-r--r--web/views/taginfo/projects.erb40
-rw-r--r--web/viewsjs/key.js.erb26
-rw-r--r--web/viewsjs/project.js.erb35
-rw-r--r--web/viewsjs/projects.js.erb23
-rw-r--r--web/viewsjs/tag.js.erb26
36 files changed, 1370 insertions, 2 deletions
diff --git a/projects/README b/projects/README
new file mode 100644
index 0000000..7637055
--- /dev/null
+++ b/projects/README
@@ -0,0 +1,2 @@
+These project files should be kept in the repositories of the different
+projects. They are in this place only to kickstart the projects effort.
diff --git a/projects/id_editor.json b/projects/id_editor.json
new file mode 100644
index 0000000..264826b
--- /dev/null
+++ b/projects/id_editor.json
@@ -0,0 +1,484 @@
+{
+ "data_format": 1,
+ "data_url": "https://raw.githubusercontent.com/joto/taginfo/master/projects/id_editor.json",
+ "project": {
+ "name": "iD Editor",
+ "description": "Online editor for OSM data.",
+ "project_url": "http://wiki.osm.org/wiki/ID",
+ "icon_url": "https://raw.githubusercontent.com/joto/taginfo/master/projects/id_editor.png",
+ "keywords": [
+ "editor"
+ ]
+ },
+ "tags": [
+{ "key": "area" },
+{ "key": "place" },
+{ "key": "embankment" },
+{ "key": "aerialway" },
+{ "key": "railway" },
+{ "key": "landuse" },
+{ "key": "point" },
+{ "key": "power" },
+{ "key": "natural" },
+{ "key": "piste" },
+{ "key": "barrier" },
+{ "key": "line" },
+{ "key": "office" },
+{ "key": "aeroway" },
+{ "key": "leisure" },
+{ "key": "entrance" },
+{ "key": "relation" },
+{ "key": "historic" },
+{ "key": "tourism" },
+{ "key": "vertex" },
+{ "key": "ford" },
+{ "key": "highway" },
+{ "key": "address" },
+{ "key": "building" },
+{ "key": "amenity" },
+{ "key": "waterway" },
+{ "key": "shop" },
+{ "key": "man_made" },
+{ "key": "type", "value": "route" },
+{ "key": "type", "value": "restriction" },
+{ "key": "type", "value": "route_master" },
+{ "key": "type", "value": "multipolygon" },
+{ "key": "type", "value": "boundary" },
+{ "key": "natural", "value": "fell" },
+{ "key": "natural", "value": "beach" },
+{ "key": "natural", "value": "tree" },
+{ "key": "natural", "value": "scrub" },
+{ "key": "natural", "value": "glacier" },
+{ "key": "natural", "value": "grassland" },
+{ "key": "natural", "value": "spring" },
+{ "key": "natural", "value": "wetland" },
+{ "key": "natural", "value": "water" },
+{ "key": "natural", "value": "coastline" },
+{ "key": "natural", "value": "scree" },
+{ "key": "natural", "value": "wood" },
+{ "key": "natural", "value": "cliff" },
+{ "key": "natural", "value": "peak" },
+{ "key": "natural", "value": "bay" },
+{ "key": "natural", "value": "heath" },
+{ "key": "aeroway", "value": "taxiway" },
+{ "key": "aeroway", "value": "aerodrome" },
+{ "key": "aeroway", "value": "apron" },
+{ "key": "aeroway", "value": "terminal" },
+{ "key": "aeroway", "value": "gate" },
+{ "key": "aeroway", "value": "runway" },
+{ "key": "aeroway", "value": "hangar" },
+{ "key": "aeroway", "value": "helipad" },
+{ "key": "waterway", "value": "canal" },
+{ "key": "waterway", "value": "river" },
+{ "key": "waterway", "value": "weir" },
+{ "key": "waterway", "value": "drain" },
+{ "key": "waterway", "value": "ditch" },
+{ "key": "waterway", "value": "dam" },
+{ "key": "waterway", "value": "riverbank" },
+{ "key": "waterway", "value": "stream" },
+{ "key": "man_made", "value": "lighthouse" },
+{ "key": "man_made", "value": "pipeline" },
+{ "key": "man_made", "value": "embankment" },
+{ "key": "man_made", "value": "survey_point" },
+{ "key": "man_made", "value": "flagpole" },
+{ "key": "man_made", "value": "pier" },
+{ "key": "man_made", "value": "breakwater" },
+{ "key": "man_made", "value": "wastewater_plant" },
+{ "key": "man_made", "value": "observation" },
+{ "key": "man_made", "value": "water_well" },
+{ "key": "man_made", "value": "water_tower" },
+{ "key": "man_made", "value": "cutline" },
+{ "key": "man_made", "value": "tower" },
+{ "key": "man_made", "value": "water_works" },
+{ "key": "leisure", "value": "picnic_table" },
+{ "key": "leisure", "value": "marina" },
+{ "key": "leisure", "value": "common" },
+{ "key": "leisure", "value": "ice_rink" },
+{ "key": "leisure", "value": "pitch" },
+{ "key": "leisure", "value": "track" },
+{ "key": "leisure", "value": "slipway" },
+{ "key": "leisure", "value": "firepit" },
+{ "key": "leisure", "value": "park" },
+{ "key": "leisure", "value": "dog_park" },
+{ "key": "leisure", "value": "garden" },
+{ "key": "leisure", "value": "sports_center" },
+{ "key": "leisure", "value": "golf_course" },
+{ "key": "leisure", "value": "stadium" },
+{ "key": "leisure", "value": "swimming_pool" },
+{ "key": "leisure", "value": "playground" },
+{ "key": "building", "value": "construction" },
+{ "key": "building", "value": "barn" },
+{ "key": "building", "value": "apartments" },
+{ "key": "building", "value": "house" },
+{ "key": "building", "value": "garages" },
+{ "key": "building", "value": "detached" },
+{ "key": "building", "value": "school" },
+{ "key": "building", "value": "retail" },
+{ "key": "building", "value": "static_caravan" },
+{ "key": "building", "value": "bunker" },
+{ "key": "building", "value": "terrace" },
+{ "key": "building", "value": "train_station" },
+{ "key": "building", "value": "garage" },
+{ "key": "building", "value": "commercial" },
+{ "key": "building", "value": "hut" },
+{ "key": "building", "value": "warehouse" },
+{ "key": "building", "value": "entrance" },
+{ "key": "building", "value": "cabin" },
+{ "key": "building", "value": "church" },
+{ "key": "building", "value": "university" },
+{ "key": "building", "value": "chapel" },
+{ "key": "building", "value": "residential" },
+{ "key": "building", "value": "industrial" },
+{ "key": "building", "value": "hotel" },
+{ "key": "building", "value": "stable" },
+{ "key": "building", "value": "roof" },
+{ "key": "building", "value": "hospital" },
+{ "key": "building", "value": "shed" },
+{ "key": "building", "value": "dormitory" },
+{ "key": "building", "value": "public" },
+{ "key": "building", "value": "cathedral" },
+{ "key": "building", "value": "greenhouse" },
+{ "key": "barrier", "value": "hedge" },
+{ "key": "barrier", "value": "fence" },
+{ "key": "barrier", "value": "wall" },
+{ "key": "barrier", "value": "cycle_barrier" },
+{ "key": "barrier", "value": "lift_gate" },
+{ "key": "barrier", "value": "ditch" },
+{ "key": "barrier", "value": "cattle_grid" },
+{ "key": "barrier", "value": "block" },
+{ "key": "barrier", "value": "city_wall" },
+{ "key": "barrier", "value": "bollard" },
+{ "key": "barrier", "value": "entrance" },
+{ "key": "barrier", "value": "gate" },
+{ "key": "barrier", "value": "stile" },
+{ "key": "barrier", "value": "toll_booth" },
+{ "key": "barrier", "value": "kissing_gate" },
+{ "key": "barrier", "value": "retaining_wall" },
+{ "key": "place", "value": "hamlet" },
+{ "key": "place", "value": "village" },
+{ "key": "place", "value": "city" },
+{ "key": "place", "value": "suburb" },
+{ "key": "place", "value": "isolated_dwelling" },
+{ "key": "place", "value": "locality" },
+{ "key": "place", "value": "neighbourhood" },
+{ "key": "place", "value": "island" },
+{ "key": "place", "value": "town" },
+{ "key": "boundary", "value": "administrative" },
+{ "key": "golf", "value": "tee" },
+{ "key": "golf", "value": "bunker" },
+{ "key": "golf", "value": "fairway" },
+{ "key": "golf", "value": "green" },
+{ "key": "golf", "value": "rough" },
+{ "key": "golf", "value": "water_hazard" },
+{ "key": "golf", "value": "lateral_water_hazard" },
+{ "key": "golf", "value": "hole" },
+{ "key": "aerialway", "value": "station" },
+{ "key": "aerialway", "value": "t-bar" },
+{ "key": "aerialway", "value": "gondola" },
+{ "key": "aerialway", "value": "pylon" },
+{ "key": "aerialway", "value": "platter" },
+{ "key": "aerialway", "value": "magic_carpet" },
+{ "key": "aerialway", "value": "chair_lift" },
+{ "key": "aerialway", "value": "rope_tow" },
+{ "key": "aerialway", "value": "cable_car" },
+{ "key": "landuse", "value": "construction" },
+{ "key": "landuse", "value": "farmyard" },
+{ "key": "landuse", "value": "forest" },
+{ "key": "landuse", "value": "cemetery" },
+{ "key": "landuse", "value": "retail" },
+{ "key": "landuse", "value": "quarry" },
+{ "key": "landuse", "value": "churchyard" },
+{ "key": "landuse", "value": "basin" },
+{ "key": "landuse", "value": "landfill" },
+{ "key": "landuse", "value": "military" },
+{ "key": "landuse", "value": "farmland" },
+{ "key": "landuse", "value": "commercial" },
+{ "key": "landuse", "value": "grass" },
+{ "key": "landuse", "value": "meadow" },
+{ "key": "landuse", "value": "residential" },
+{ "key": "landuse", "value": "industrial" },
+{ "key": "landuse", "value": "orchard" },
+{ "key": "landuse", "value": "vineyard" },
+{ "key": "landuse", "value": "allotments" },
+{ "key": "landuse", "value": "farm" },
+{ "key": "military", "value": "barracks" },
+{ "key": "military", "value": "bunker" },
+{ "key": "military", "value": "airfield" },
+{ "key": "military", "value": "range" },
+{ "key": "craft", "value": "locksmith" },
+{ "key": "craft", "value": "caterer" },
+{ "key": "craft", "value": "confectionary" },
+{ "key": "craft", "value": "sailmaker" },
+{ "key": "craft", "value": "sawmill" },
+{ "key": "craft", "value": "shoemaker" },
+{ "key": "craft", "value": "optician" },
+{ "key": "craft", "value": "key_cutter" },
+{ "key": "craft", "value": "rigger" },
+{ "key": "craft", "value": "clockmaker" },
+{ "key": "craft", "value": "pottery" },
+{ "key": "craft", "value": "blacksmith" },
+{ "key": "craft", "value": "photographic_laboratory" },
+{ "key": "craft", "value": "insulator" },
+{ "key": "craft", "value": "window_construction" },
+{ "key": "craft", "value": "brewery" },
+{ "key": "craft", "value": "carpenter" },
+{ "key": "craft", "value": "handicraft" },
+{ "key": "craft", "value": "tiler" },
+{ "key": "craft", "value": "glaziery" },
+{ "key": "craft", "value": "watchmaker" },
+{ "key": "craft", "value": "electrician" },
+{ "key": "craft", "value": "jeweler" },
+{ "key": "craft", "value": "scaffolder" },
+{ "key": "craft", "value": "bookbinder" },
+{ "key": "craft", "value": "sweep" },
+{ "key": "craft", "value": "metal_construction" },
+{ "key": "craft", "value": "basket_maker" },
+{ "key": "craft", "value": "gardener" },
+{ "key": "craft", "value": "hvac" },
+{ "key": "craft", "value": "saddler" },
+{ "key": "craft", "value": "tailor" },
+{ "key": "craft", "value": "dressmaker" },
+{ "key": "craft", "value": "upholsterer" },
+{ "key": "craft", "value": "painter" },
+{ "key": "craft", "value": "tinsmith" },
+{ "key": "craft", "value": "photographer" },
+{ "key": "craft", "value": "carpet_layer" },
+{ "key": "craft", "value": "roofer" },
+{ "key": "craft", "value": "boatbuilder" },
+{ "key": "craft", "value": "beekeeper" },
+{ "key": "craft", "value": "plasterer" },
+{ "key": "craft", "value": "stonemason" },
+{ "key": "craft", "value": "sculpter" },
+{ "key": "craft", "value": "plumber" },
+{ "key": "office", "value": "therapist" },
+{ "key": "office", "value": "newspaper" },
+{ "key": "office", "value": "travel_agent" },
+{ "key": "office", "value": "company" },
+{ "key": "office", "value": "educational_institution" },
+{ "key": "office", "value": "accountant" },
+{ "key": "office", "value": "lawyer" },
+{ "key": "office", "value": "physician" },
+{ "key": "office", "value": "architect" },
+{ "key": "office", "value": "research" },
+{ "key": "office", "value": "political_party" },
+{ "key": "office", "value": "ngo" },
+{ "key": "office", "value": "employment_agency" },
+{ "key": "office", "value": "it" },
+{ "key": "office", "value": "administrative" },
+{ "key": "office", "value": "estate_agent" },
+{ "key": "office", "value": "financial" },
+{ "key": "office", "value": "telecommunication" },
+{ "key": "office", "value": "insurance" },
+{ "key": "office", "value": "government" },
+{ "key": "emergency", "value": "phone" },
+{ "key": "emergency", "value": "fire_hydrant" },
+{ "key": "emergency", "value": "ambulance_station" },
+{ "key": "railway", "value": "tram" },
+{ "key": "railway", "value": "station" },
+{ "key": "railway", "value": "halt" },
+{ "key": "railway", "value": "platform" },
+{ "key": "railway", "value": "disused" },
+{ "key": "railway", "value": "narrow_gauge" },
+{ "key": "railway", "value": "subway_entrance" },
+{ "key": "railway", "value": "abandoned" },
+{ "key": "railway", "value": "monorail" },
+{ "key": "railway", "value": "level_crossing" },
+{ "key": "railway", "value": "rail" },
+{ "key": "railway", "value": "subway" },
+{ "key": "railway", "value": "funicular" },
+{ "key": "route", "value": "ferry" },
+{ "key": "amenity", "value": "grave_yard" },
+{ "key": "amenity", "value": "car_sharing" },
+{ "key": "amenity", "value": "taxi" },
+{ "key": "amenity", "value": "studio" },
+{ "key": "amenity", "value": "college" },
+{ "key": "amenity", "value": "telephone" },
+{ "key": "amenity", "value": "kindergarten" },
+{ "key": "amenity", "value": "arts_centre" },
+{ "key": "amenity", "value": "fast_food" },
+{ "key": "amenity", "value": "fuel" },
+{ "key": "amenity", "value": "parking" },
+{ "key": "amenity", "value": "school" },
+{ "key": "amenity", "value": "clinic" },
+{ "key": "amenity", "value": "charging_station" },
+{ "key": "amenity", "value": "bar" },
+{ "key": "amenity", "value": "pharmacy" },
+{ "key": "amenity", "value": "library" },
+{ "key": "amenity", "value": "vending_machine" },
+{ "key": "amenity", "value": "drinking_water" },
+{ "key": "amenity", "value": "doctor" },
+{ "key": "amenity", "value": "bank" },
+{ "key": "amenity", "value": "place_of_worship" },
+{ "key": "amenity", "value": "theatre" },
+{ "key": "amenity", "value": "fire_station" },
+{ "key": "amenity", "value": "childcare" },
+{ "key": "amenity", "value": "nightclub" },
+{ "key": "amenity", "value": "bbq" },
+{ "key": "amenity", "value": "veterinary" },
+{ "key": "amenity", "value": "shelter" },
+{ "key": "amenity", "value": "bicycle_rental" },
+{ "key": "amenity", "value": "dentist" },
+{ "key": "amenity", "value": "bench" },
+{ "key": "amenity", "value": "cafe" },
+{ "key": "amenity", "value": "post_box" },
+{ "key": "amenity", "value": "ranger_station" },
+{ "key": "amenity", "value": "pub" },
+{ "key": "amenity", "value": "car_wash" },
+{ "key": "amenity", "value": "university" },
+{ "key": "amenity", "value": "embassy" },
+{ "key": "amenity", "value": "compressed_air" },
+{ "key": "amenity", "value": "courthouse" },
+{ "key": "amenity", "value": "dojo" },
+{ "key": "amenity", "value": "parking_entrance" },
+{ "key": "amenity", "value": "atm" },
+{ "key": "amenity", "value": "marketplace" },
+{ "key": "amenity", "value": "clock" },
+{ "key": "amenity", "value": "post_office" },
+{ "key": "amenity", "value": "fountain" },
+{ "key": "amenity", "value": "police" },
+{ "key": "amenity", "value": "bicycle_parking" },
+{ "key": "amenity", "value": "car_rental" },
+{ "key": "amenity", "value": "waste_basket" },
+{ "key": "amenity", "value": "recycling" },
+{ "key": "amenity", "value": "hospital" },
+{ "key": "amenity", "value": "cinema" },
+{ "key": "amenity", "value": "bureau_de_change" },
+{ "key": "amenity", "value": "townhall" },
+{ "key": "amenity", "value": "bus_station" },
+{ "key": "amenity", "value": "toilets" },
+{ "key": "amenity", "value": "swimming_pool" },
+{ "key": "amenity", "value": "social_facility" },
+{ "key": "amenity", "value": "restaurant" },
+{ "key": "amenity", "value": "boat_rental" },
+{ "key": "highway", "value": "service" },
+{ "key": "highway", "value": "road" },
+{ "key": "highway", "value": "primary" },
+{ "key": "highway", "value": "crossing" },
+{ "key": "highway", "value": "track" },
+{ "key": "highway", "value": "tertiary" },
+{ "key": "highway", "value": "services" },
+{ "key": "highway", "value": "street_lamp" },
+{ "key": "highway", "value": "motorway_junction" },
+{ "key": "highway", "value": "motorway_link" },
+{ "key": "highway", "value": "motorway" },
+{ "key": "highway", "value": "rest_area" },
+{ "key": "highway", "value": "secondary_link" },
+{ "key": "highway", "value": "path" },
+{ "key": "highway", "value": "trunk_link" },
+{ "key": "highway", "value": "tertiary_link" },
+{ "key": "highway", "value": "secondary" },
+{ "key": "highway", "value": "cycleway" },
+{ "key": "highway", "value": "trunk" },
+{ "key": "highway", "value": "traffic_signals" },
+{ "key": "highway", "value": "mini_roundabout" },
+{ "key": "highway", "value": "bus_stop" },
+{ "key": "highway", "value": "living_street" },
+{ "key": "highway", "value": "residential" },
+{ "key": "highway", "value": "steps" },
+{ "key": "highway", "value": "primary_link" },
+{ "key": "highway", "value": "unclassified" },
+{ "key": "highway", "value": "bridleway" },
+{ "key": "highway", "value": "stop" },
+{ "key": "highway", "value": "turning_circle" },
+{ "key": "highway", "value": "footway" },
+{ "key": "highway", "value": "crosswalk" },
+{ "key": "highway", "value": "pedestrian" },
+{ "key": "tourism", "value": "viewpoint" },
+{ "key": "tourism", "value": "hostel" },
+{ "key": "tourism", "value": "camp_site" },
+{ "key": "tourism", "value": "theme_park" },
+{ "key": "tourism", "value": "alpine_hut" },
+{ "key": "tourism", "value": "zoo" },
+{ "key": "tourism", "value": "information" },
+{ "key": "tourism", "value": "attraction" },
+{ "key": "tourism", "value": "guest_house" },
+{ "key": "tourism", "value": "picnic_site" },
+{ "key": "tourism", "value": "caravan_site" },
+{ "key": "tourism", "value": "museum" },
+{ "key": "tourism", "value": "hotel" },
+{ "key": "tourism", "value": "motel" },
+{ "key": "tourism", "value": "chalet" },
+{ "key": "tourism", "value": "artwork" },
+{ "key": "shop", "value": "locksmith" },
+{ "key": "shop", "value": "kiosk" },
+{ "key": "shop", "value": "photo" },
+{ "key": "shop", "value": "electronics" },
+{ "key": "shop", "value": "pet" },
+{ "key": "shop", "value": "vacant" },
+{ "key": "shop", "value": "video" },
+{ "key": "shop", "value": "bicycle" },
+{ "key": "shop", "value": "alcohol" },
+{ "key": "shop", "value": "dry_cleaning" },
+{ "key": "shop", "value": "newsagent" },
+{ "key": "shop", "value": "laundry" },
+{ "key": "shop", "value": "hairdresser" },
+{ "key": "shop", "value": "jewelry" },
+{ "key": "shop", "value": "optician" },
+{ "key": "shop", "value": "car_repair" },
+{ "key": "shop", "value": "motorcycle" },
+{ "key": "shop", "value": "clothes" },
+{ "key": "shop", "value": "seafood" },
+{ "key": "shop", "value": "convenience" },
+{ "key": "shop", "value": "beauty" },
+{ "key": "shop", "value": "car" },
+{ "key": "shop", "value": "department_store" },
+{ "key": "shop", "value": "sports" },
+{ "key": "shop", "value": "lottery" },
+{ "key": "shop", "value": "boutique" },
+{ "key": "shop", "value": "outdoor" },
+{ "key": "shop", "value": "butcher" },
+{ "key": "shop", "value": "gift" },
+{ "key": "shop", "value": "music" },
+{ "key": "shop", "value": "furniture" },
+{ "key": "shop", "value": "fishmonger" },
+{ "key": "shop", "value": "deli" },
+{ "key": "shop", "value": "art" },
+{ "key": "shop", "value": "chemist" },
+{ "key": "shop", "value": "funeral_directors" },
+{ "key": "shop", "value": "supermarket" },
+{ "key": "shop", "value": "toys" },
+{ "key": "shop", "value": "variety_store" },
+{ "key": "shop", "value": "shoes" },
+{ "key": "shop", "value": "stationery" },
+{ "key": "shop", "value": "tyres" },
+{ "key": "shop", "value": "confectionery" },
+{ "key": "shop", "value": "tailor" },
+{ "key": "shop", "value": "beverages" },
+{ "key": "shop", "value": "florist" },
+{ "key": "shop", "value": "hardware" },
+{ "key": "shop", "value": "bookmaker" },
+{ "key": "shop", "value": "doityourself" },
+{ "key": "shop", "value": "hifi" },
+{ "key": "shop", "value": "car_parts" },
+{ "key": "shop", "value": "mobile_phone" },
+{ "key": "shop", "value": "greengrocer" },
+{ "key": "shop", "value": "mall" },
+{ "key": "shop", "value": "bakery" },
+{ "key": "shop", "value": "travel_agency" },
+{ "key": "shop", "value": "computer" },
+{ "key": "shop", "value": "books" },
+{ "key": "shop", "value": "wine" },
+{ "key": "shop", "value": "garden_centre" },
+{ "key": "shop", "value": "farm" },
+{ "key": "public_transport", "value": "platform" },
+{ "key": "public_transport", "value": "stop_position" },
+{ "key": "footway", "value": "crossing" },
+{ "key": "footway", "value": "sidewalk" },
+{ "key": "footway", "value": "crosswalk" },
+{ "key": "historic", "value": "monument" },
+{ "key": "historic", "value": "castle" },
+{ "key": "historic", "value": "wayside_shrine" },
+{ "key": "historic", "value": "wayside_cross" },
+{ "key": "historic", "value": "boundary_stone" },
+{ "key": "historic", "value": "ruins" },
+{ "key": "historic", "value": "archaeological_site" },
+{ "key": "historic", "value": "memorial" },
+{ "key": "power", "value": "minor_line" },
+{ "key": "power", "value": "pole" },
+{ "key": "power", "value": "generator" },
+{ "key": "power", "value": "line" },
+{ "key": "power", "value": "transformer" },
+{ "key": "power", "value": "sub_station" },
+{ "key": "power", "value": "tower" }
+ ]
+}
diff --git a/projects/id_editor.png b/projects/id_editor.png
new file mode 100644
index 0000000..96b184f
--- /dev/null
+++ b/projects/id_editor.png
Binary files differ
diff --git a/projects/osrm.json b/projects/osrm.json
new file mode 100644
index 0000000..c4aabaa
--- /dev/null
+++ b/projects/osrm.json
@@ -0,0 +1,41 @@
+{
+ "data_format": 1,
+ "data_url": "https://raw.githubusercontent.com/joto/taginfo/master/projects/osrm.json",
+ "project": {
+ "name": "Open Source Routing Machine",
+ "description": "High-performance routing engine for shortest paths in road networks.",
+ "project_url": "http://project-osrm.org",
+ "icon_url": "https://raw.githubusercontent.com/joto/taginfo/master/projects/osrm.png",
+ "contact_name": "",
+ "contact_email": ""
+ },
+ "tags": [
+ {
+ "key": "highway"
+ },
+ {
+ "key": "oneway"
+ },
+ {
+ "key": "access"
+ },
+ {
+ "key": "barrier"
+ },
+ {
+ "key": "maxspeed"
+ },
+ {
+ "key": "name",
+ "description": "Name of road for navigation instructions."
+ },
+ {
+ "key": "junction",
+ "value": "roundabout"
+ },
+ {
+ "key": "type",
+ "value": "restriction"
+ }
+ ]
+}
diff --git a/projects/osrm.png b/projects/osrm.png
new file mode 100644
index 0000000..a08df46
--- /dev/null
+++ b/projects/osrm.png
Binary files differ
diff --git a/sources/projects/import.rb b/sources/projects/import.rb
new file mode 100755
index 0000000..820bf02
--- /dev/null
+++ b/sources/projects/import.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/ruby
+#------------------------------------------------------------------------------
+#
+# Taginfo source: Projects
+#
+# import.rb
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (C) 2014 Jochen Topf <jochen@remote.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+#------------------------------------------------------------------------------
+
+require 'net/http'
+require 'sqlite3'
+require 'time'
+
+#------------------------------------------------------------------------------
+
+dir = ARGV[0] || '.'
+db = SQLite3::Database.new(dir + '/taginfo-projects.db')
+
+project_list = ARGV[1] || 'project_list.txt'
+
+#------------------------------------------------------------------------------
+
+projects = []
+open(project_list) do |file|
+ file.each do |line|
+ projects << line.chomp.split(' ')
+ end
+end
+
+projects.each do |id, url|
+ puts " #{id} #{url}"
+ uri = URI(url)
+ Net::HTTP.start(uri.host, uri.port) do |http|
+ request = Net::HTTP::Get.new(uri)
+ response = http.request(request)
+ last_modified = Time.parse(response['Last-Modified']).utc.iso8601
+ db.execute("INSERT INTO projects (id, json_url, last_modified, fetch_date, fetch_status, fetch_json, fetch_result, data_updated) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
+ id,
+ url,
+ last_modified,
+ Time.now.utc.iso8601,
+ response.code,
+ response.body,
+ (response.code == '200' ? 'OK' : 'FETCH ERROR'),
+ last_modified
+ );
+ end
+end
+
+
+#-- THE END -------------------------------------------------------------------
diff --git a/sources/projects/parse.rb b/sources/projects/parse.rb
new file mode 100755
index 0000000..c509fae
--- /dev/null
+++ b/sources/projects/parse.rb
@@ -0,0 +1,85 @@
+#!/usr/bin/ruby
+#------------------------------------------------------------------------------
+#
+# Taginfo source: Projects
+#
+# parse.rb
+#
+#------------------------------------------------------------------------------
+#
+# Copyright (C) 2014 Jochen Topf <jochen@remote.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+#------------------------------------------------------------------------------
+
+require 'pp'
+require 'json'
+require 'sqlite3'
+
+#------------------------------------------------------------------------------
+
+dir = ARGV[0] || '.'
+db = SQLite3::Database.new(dir + '/taginfo-projects.db')
+
+#------------------------------------------------------------------------------
+
+projects = db.execute("SELECT id, fetch_json FROM projects WHERE fetch_result='OK' ORDER BY id")
+
+projects.each do |id, json|
+ puts " #{id}..."
+ begin
+ data = JSON.parse(json, { :symbolize_names => true, :create_additions => false })
+ db.transaction do |db|
+ db.execute("UPDATE projects SET data_format=?, data_url=? WHERE id=?", data[:data_format], data[:data_url], id)
+
+ if data[:data_updated]
+ db.execute("UPDATE projects SET data_updated=? WHERE id=?", data[:data_updated], id)
+ end
+
+ if data[:project]
+ p = data[:project]
+ db.execute("UPDATE projects SET name=?, description=?, project_url=?, doc_url=?, icon_url=?, contact_name=?, contact_email=? WHERE id=?",
+ p[:name],
+ p[:description],
+ p[:project_url],
+ p[:doc_url],
+ p[:icon_url],
+ p[:contact_name],
+ p[:contact_email],
+ id
+ )
+ end
+
+ if data[:tags]
+ data[:tags].each do |d|
+ db.execute("INSERT INTO project_tags (project_id, key, value, description, doc_url, icon_url) VALUES (?, ?, ?, ?, ?, ?)",
+ id,
+ d[:key],
+ d[:value],
+ d[:description],
+ d[:doc_url],
+ d[:icon_url]
+ );
+ end
+ end
+ end
+ rescue JSON::ParserError
+ db.execute("UPDATE projects SET fetch_result='PARSE_ERROR' WHERE id=?", id)
+ end
+end
+
+
+#-- THE END -------------------------------------------------------------------
diff --git a/sources/projects/post.sql b/sources/projects/post.sql
new file mode 100644
index 0000000..b8d210f
--- /dev/null
+++ b/sources/projects/post.sql
@@ -0,0 +1,15 @@
+--
+-- Taginfo source: Projects
+--
+-- post.sql
+--
+
+.bail ON
+
+CREATE INDEX project_keys_idx ON project_tags (key) WHERE value IS NULL;
+CREATE INDEX project_tags_idx ON project_tags (key, value) WHERE value IS NOT NULL;
+
+ANALYZE;
+
+UPDATE source SET update_end=datetime('now');
+
diff --git a/sources/projects/pre.sql b/sources/projects/pre.sql
new file mode 100644
index 0000000..da4d66f
--- /dev/null
+++ b/sources/projects/pre.sql
@@ -0,0 +1,46 @@
+--
+-- Taginfo source: Projects
+--
+-- pre.sql
+--
+
+.bail ON
+
+INSERT INTO source (id, name, update_start, data_until) SELECT 'projects', 'Projects', datetime('now'), datetime('now');
+
+DROP TABLE IF EXISTS projects;
+
+CREATE TABLE projects (
+ id TEXT NOT NULL PRIMARY KEY,
+ json_url TEXT NOT NULL,
+ last_modified DATE,
+ fetch_date DATE,
+ fetch_status TEXT, -- HTTP status code
+ fetch_json TEXT, -- HTTP body
+ fetch_result TEXT, -- 'OK', 'FETCH ERROR', 'PARSE ERROR'
+ data_format INTEGER,
+ data_updated DATE,
+ data_url TEXT,
+ icon BLOB,
+ name TEXT,
+ description TEXT,
+ project_url TEXT,
+ doc_url TEXT,
+ icon_url TEXT,
+ contact_name TEXT,
+ contact_email TEXT,
+ keywords TEXT
+);
+
+DROP TABLE IF EXISTS project_tags;
+
+CREATE TABLE project_tags (
+ project_id TEXT NOT NULL,
+ key TEXT NOT NULL,
+ value TEXT,
+ description TEXT,
+ doc_url TEXT,
+ icon_url TEXT,
+ keywords TEXT
+);
+
diff --git a/sources/projects/project_list.txt b/sources/projects/project_list.txt
new file mode 100644
index 0000000..479724b
--- /dev/null
+++ b/sources/projects/project_list.txt
@@ -0,0 +1,4 @@
+id_editor https://raw.githubusercontent.com/joto/taginfo/master/projects/id_editor.json
+osmcoastline https://raw.githubusercontent.com/joto/osmcoastline/master/taginfo-project.json
+osrm https://raw.githubusercontent.com/joto/taginfo/master/projects/osrm.json
+waymarkedtrails http://mapstatic.waymarkedtrails.org/taginfo.json
diff --git a/sources/projects/update.sh b/sources/projects/update.sh
new file mode 100755
index 0000000..6c05ac9
--- /dev/null
+++ b/sources/projects/update.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Taginfo source: Projects
+#
+# update.sh DIR
+#
+
+set -e
+
+DIR=$1
+PROJECT_LIST=project_list.txt
+
+DATECMD='date +%Y-%m-%dT%H:%M:%S'
+
+if [ "x" = "x$DIR" ]; then
+ echo "Usage: update.sh DIR"
+ exit 1
+fi
+
+echo "`$DATECMD` Start projects..."
+
+EXEC_RUBY="$TAGINFO_RUBY"
+if [ "x$EXEC_RUBY" = "x" ]; then
+ EXEC_RUBY=ruby
+fi
+echo "Running with ruby set as '${EXEC_RUBY}'"
+
+DATABASE=$DIR/taginfo-projects.db
+
+rm -f $DATABASE
+
+echo "`$DATECMD` Running init.sql..."
+sqlite3 $DATABASE <../init.sql
+
+echo "`$DATECMD` Running pre.sql..."
+sqlite3 $DATABASE <pre.sql
+
+echo "`$DATECMD` Getting data files..."
+$EXEC_RUBY ./import.rb $DIR $PROJECT_LIST
+
+echo "`$DATECMD` Parsing data files..."
+$EXEC_RUBY ./parse.rb $DIR
+
+echo "`$DATECMD` Running post.sql..."
+sqlite3 $DATABASE <post.sql
+
+echo "`$DATECMD` Done projects."
+
diff --git a/web/i18n/de.yml b/web/i18n/de.yml
index 7b07685..45e4596 100644
--- a/web/i18n/de.yml
+++ b/web/i18n/de.yml
@@ -38,6 +38,8 @@ taginfo:
reports: Reports
international: International
apidoc: API-Dokumentation
+ project: Projekt
+ projects: Projekte
test: Test
map: Karte
maps: Karten
@@ -168,6 +170,8 @@ pages:
<p>Taginfo bekommt Informationen über die verschiedenen Sprachen dieser Welt, ihre Codes, Namen, usw. aus diversen Datenbanken der <a class="extlink" href="http://www.iana.org/">IANA</a> und vom <a class="extlink" href="http://www.unicode.org/">Unicode Consortium</a>.</p>
josm: |
<p>Icons und Stile werden aus der Konfiguration des Editors <a class="extlink" href="http://josm.openstreetmap.de/">JOSM</a> übernommen.</p>
+ projects: |
+ <p>Projekte, die OSM-Tags in irgendeiner Weise nutzen, zum Beispiel Editoren, Karten, Router, usw. Siehe auch die <a href="/projects">Projektliste</a>.</p>
updates:
title: Aktualisierung
intro: Die Taginfo-Daten werden regelmäßig aktualisiert.
@@ -223,6 +227,9 @@ pages:
no_information: Keine Informationen
roles_less_than_one_percent: Keine Roles mit mehr als 1%
empty_role: Role ist leer
+ projects:
+ intro: |
+ Diese Tabelle zeigt alle Projekte, die taginfo kennt, und die OSM-Tags in irgendeiner Weise nutzen.
key:
description_from_wiki: Beschreibung dieses Keys aus dem Wiki (falls vorhanden in der gewählten Sprache, sonst auf Englisch).
no_description_in_wiki: Keine deutschsprachige Beschreibung dieses Keys im Wiki. (Siehe auch im "Wiki"-Tab.)
@@ -264,6 +271,8 @@ pages:
choice: |
Stil auswählen:
no_styles: Keine JOSM-Stilregeln für diesen Key.
+ projects:
+ title: Projekte, die diesen Key benutzen
tag:
description_from_wiki: Beschreibung dieses Tags aus dem Wiki (falls vorhanden in der gewählten Sprache, sonst auf Englisch).
no_description_in_wiki: Keine deutschsprachige Beschreibung dieses Tags im Wiki. (Siehe auch im "Wiki"-Tab.)
@@ -298,6 +307,8 @@ pages:
choice: |
Stil auswählen:
no_styles: Keine JOSM-Stilregeln für diesen Tag.
+ projects:
+ title: Projekte, die diesen Tag benutzen
relation:
name: Relation-Typ
description_from_wiki: Beschreibung dieses Relations-Types aus dem Wiki (falls vorhanden in der gewählten Sprache, sonst auf Englisch).
@@ -325,6 +336,16 @@ pages:
none_found: Keine Wiki-Seiten für diesen Relation-Typ vorhanden.
create: Wiki-Seite für diesen Relation-Typ anlegen
wiki_page: Wiki-Seite
+ project:
+ overview:
+ project_name: Projektname
+ project_url: Projekt-URL
+ description: Beschreibung
+ documentation_url: Dokumentation
+ last_update: Letzte Aktualisierung
+ tags:
+ title: Tags, die von diesem Projekt verwenden werden
+ intro: Die folgenden Daten wurden von dem Projekt zur Verfügung gestellt. Sie sind nicht notwendigerweise komplett. Für Details schau bitte in die Projekt-Dokumentation.
flexigrid:
pagetext: Seite
diff --git a/web/i18n/en.yml b/web/i18n/en.yml
index 3c2d478..8b6963c 100644
--- a/web/i18n/en.yml
+++ b/web/i18n/en.yml
@@ -39,6 +39,8 @@ taginfo:
reports: Reports
international: International
apidoc: API Documentation
+ project: Project
+ projects: Projects
test: Test
map: Map
maps: Maps
@@ -243,6 +245,8 @@ pages:
<p>Taginfo gets information about the different languages of the world, their codes, names, etc. from several <a class="extlink" href="http://www.iana.org/">IANA</a> and <a class="extlink" href="http://www.unicode.org/">Unicode</a> registries.</p>
josm: |
<p>Icons and styles are taken from the <a class="extlink" href="http://josm.openstreetmap.de/">JOSM editor</a> configuration.</p>
+ projects: |
+ <p>Projects that use OSM tags in some way, such as editors, maps, routers, etc. See <a href="/projects">the project list</a>.</p>
updates:
title: Updates
intro: The taginfo data is updated regularly from the sources.
@@ -293,6 +297,9 @@ pages:
no_information: No information
roles_less_than_one_percent: no roles with more than 1%
empty_role: empty role
+ projects:
+ intro: |
+ This table shows all projects known to taginfo that use OSM tags in some way.
key:
description_from_wiki: Description of this key from the wiki (if available in your chosen language, otherwise in English).
no_description_in_wiki: No English language description for this key in the wiki. (See also the "Wiki" tab.)
@@ -334,6 +341,8 @@ pages:
choice: |
Choose style:
no_styles: No JOSM styles for this key.
+ projects:
+ title: Projects using this key
tag:
description_from_wiki: Description of this tag from the wiki (if available in your chosen language, otherwise in English).
no_description_in_wiki: No English language description for this tag in the wiki. (See also the "Wiki" tab.)
@@ -368,6 +377,8 @@ pages:
choice: |
Choose style:
no_styles: No JOSM styles for this tag.
+ projects:
+ title: Projects using this tag
relation:
name: Relation type
description_from_wiki: Description of this relation type from the wiki (if available in your chosen language, otherwise in English).
@@ -395,6 +406,16 @@ pages:
none_found: No wiki page available for this relation type.
create: Create wiki page for this relation type
wiki_page: Wiki page
+ project:
+ overview:
+ project_name: Project name
+ project_url: Project URL
+ description: Description
+ documentation_url: Documentation
+ last_update: Last update
+ tags:
+ title: Tags used by this project
+ intro: This data is supplied by the project and not necessarily complete. Please see the project documentation for details.
flexigrid:
pagetext: Page
diff --git a/web/lib/api/v4/project.rb b/web/lib/api/v4/project.rb
new file mode 100644
index 0000000..94eeadc
--- /dev/null
+++ b/web/lib/api/v4/project.rb
@@ -0,0 +1,66 @@
+# web/lib/api/v4/project.rb
+class Taginfo < Sinatra::Base
+
+ api(4, 'project/tags', {
+ :description => 'Get list of all keys/tags used by a project.',
+ :parameters => { :project => 'Project ID' },
+ :paging => :optional,
+ :sort => %w( tag ),
+ :result => paging_results([
+ [:key, :STRING, 'Key'],
+ [:value, :STRING, 'Value'],
+ [:description, :STRING, 'Description'],
+ [:doc_url, :STRING, 'Documentation URL'],
+ [:icon_url, :STRING, 'Icon URL']
+ ]),
+ :example => { :page => 1, :rp => 10, :sortname => 'key', :sortorder => 'asc' },
+ :ui => '/projects/id_editor'
+ }) do
+ project_id = params[:project]
+
+ q = like_contains(params[:query])
+ total = @db.count('projects.project_tags').
+ condition("project_id=?", project_id).
+ condition_if("key LIKE ? ESCAPE '@' OR value LIKE ? ESCAPE '@'", q, q).
+ get_first_value().to_i
+
+ res = @db.select('SELECT * FROM projects.project_tags').
+ condition("project_id=?", project_id).
+ condition_if("key LIKE ? ESCAPE '@' OR value LIKE ? ESCAPE '@'", q, q).
+ order_by(@ap.sortname, @ap.sortorder) { |o|
+ o.tag :key
+ o.tag :value
+ }.
+ paging(@ap).
+ execute()
+
+ return JSON.generate({
+ :page => @ap.page,
+ :rp => @ap.results_per_page,
+ :total => total,
+ :url => request.url,
+ :data => res.map{ |row| {
+ :key => row['key'],
+ :value => row['value'],
+ :description => row['description'],
+ :doc_url => row['doc_url'],
+ :icon_url => row['icon_url']
+ }}
+ }, json_opts(params[:format]))
+ end
+
+ api(4, 'project/icon', {
+ :description => 'Access logo icon for project.',
+ :parameters => { :project => 'Project ID' },
+ :result => 'PNG image.',
+ :example => { :project => 'osmcoastline' },
+ :ui => '/projects'
+ }) do
+ project_id = params[:project]
+ content_type :png
+ @db.select('SELECT icon FROM projects.projects').
+ condition('id = ?', project_id).
+ get_first_value()
+ end
+
+end
diff --git a/web/lib/api/v4/projects.rb b/web/lib/api/v4/projects.rb
new file mode 100644
index 0000000..2cbb7fb
--- /dev/null
+++ b/web/lib/api/v4/projects.rb
@@ -0,0 +1,53 @@
+# web/lib/api/v4/projects.rb
+class Taginfo < Sinatra::Base
+
+ api(4, 'projects/all', {
+ :description => 'Get list of all projects using OSM tags known to taginfo.',
+ :parameters => { :status => 'Only show projects with given status (default is "OK")', :query => 'Only show projects matching this query (substring match, optional).' },
+ :paging => :optional,
+ :sort => %w( name ),
+ :result => paging_results([
+ [:id, :STRING, 'Project id'],
+ [:name, :STRING, 'Project name'],
+ [:url, :STRING, 'Project URL'],
+ [:description, :STRING, 'Project description']
+ ]),
+ :example => { :page => 1, :rp => 10, :sortname => 'name', :sortorder => 'asc' },
+ :ui => '/projects'
+ }) do
+ if params[:status]
+ status = params[:status]
+ else
+ status = 'OK'
+ end
+
+ q = like_contains(params[:query])
+ total = @db.count('projects.projects').
+ condition("fetch_result=?", status).
+ condition_if("name LIKE ? ESCAPE '@' OR description LIKE ? ESCAPE '@'", q, q).
+ get_first_value().to_i
+
+ res = @db.select('SELECT * FROM projects.projects').
+ condition("fetch_result=?", status).
+ condition_if("name LIKE ? ESCAPE '@' OR description LIKE ? ESCAPE '@'", q, q).
+ order_by(@ap.sortname, @ap.sortorder) { |o|
+ o.name 'lower(name)'
+ }.
+ paging(@ap).
+ execute()
+
+ return JSON.generate({
+ :page => @ap.page,
+ :rp => @ap.results_per_page,
+ :total => total,
+ :url => request.url,
+ :data => res.map{ |row| {
+ :id => row['id'],
+ :name => row['name'],
+ :url => row['project_url'],
+ :description => row['description'],
+ }}
+ }, json_opts(params[:format]))
+ end
+
+end
diff --git a/web/lib/api/v4/tag.rb b/web/lib/api/v4/tag.rb
index 152569a..f2ca53b 100644
--- a/web/lib/api/v4/tag.rb
+++ b/web/lib/api/v4/tag.rb
@@ -248,4 +248,67 @@ class Taginfo < Sinatra::Base
return get_wiki_result(res)
end
+ api(4, 'tag/projects', {
+ :description => 'Get projects using a given key or tag.',
+ :parameters => {
+ :key => 'Tag key (required).',
+ :value => 'Tag value (optional).',
+ :query => 'Only show results where the value matches this query (substring match, optional).'
+ },
+ :paging => :optional,
+ :sort => %w( project_name key value ),
+ :result => paging_results([
+ [:project_id, :STRING, 'Project ID'],
+ [:project_name, :STRING, 'Project name'],
+ [:key, :STRING, 'Key'],
+ [:value, :STRING, 'Value'],
+ [:description, :STRING, 'Description'],
+ [:doc_url, :STRING, 'Documentation URL'],
+ [:icon_url, :STRING, 'Icon URL']
+ ]),
+ :example => { :key => 'highway', :value => 'residential', :page => 1, :rp => 10, :sortname => 'project_name', :sortorder => 'asc' },
+ :ui => '/keys/highway=residential#projects'
+ }) do
+ key = params[:key]
+ value = params[:value]
+ q = like_contains(params[:query])
+ total = @db.select('SELECT count(*) FROM projects.projects p, projects.project_tags t ON p.id=t.project_id').
+ condition('key = ?', key).
+ condition_if('value = ? OR VALUE IS NULL', value).
+ condition_if("value LIKE ? ESCAPE '@' OR name LIKE ? ESCAPE '@'", q, q).
+ get_first_value().to_i
+
+ res = @db.select('SELECT t.project_id, p.name, t.key, t.value, t.description, t.doc_url, t.icon_url FROM projects.projects p, projects.project_tags t ON p.id=t.project_id').
+ condition('key = ?', key).
+ condition_if('value = ? OR VALUE IS NULL', value).
+ condition_if("value LIKE ? ESCAPE '@' OR name LIKE ? ESCAPE '@'", q, q).
+ order_by(@ap.sortname, @ap.sortorder) { |o|
+ o.project_name 'p.name'
+ o.project_name :key
+ o.project_name :value
+ o.key :key
+ o.key :value
+ o.value :value
+ o.value :key
+ }.
+ paging(@ap).
+ execute()
+
+ return JSON.generate({
+ :page => @ap.page,
+ :rp => @ap.results_per_page,
+ :total => total.to_i,
+ :url => request.url,
+ :data => res.map{ |row| {
+ :project_id => row['project_id'],
+ :project_name => row['name'],
+ :key => row['key'],
+ :value => row['value'],
+ :description => row['description'],
+ :doc_url => row['doc_url'],
+ :icon_url => row['icon_url']
+ } }
+ }, json_opts(params[:format]))
+ end
+
end
diff --git a/web/lib/projects.rb b/web/lib/projects.rb
new file mode 100644
index 0000000..01536a2
--- /dev/null
+++ b/web/lib/projects.rb
@@ -0,0 +1,51 @@
+# web/lib/projects.rb
+class Project
+
+ @@projects = Array.new
+
+ @@attrs = [:id, :json_url, :fetch_date, :fetch_status, :fetch_json, :fetch_result, :data_format, :data_updated, :data_url, :name, :project_url, :doc_url, :icon_url, :description, :contact_name, :contact_email]
+
+ @@attrs.each do |attr|
+ attr_reader attr
+ end
+
+ # Enumerate all available projects
+ def self.each
+ @@projects.each do |project|
+ yield project
+ end
+ end
+
+ # Enumerate all available projects
+ def self.each_with_index
+ @@projects.each_with_index do |project, n|
+ yield project, n
+ end
+ end
+
+ # The number of available sources
+ def self.size
+ @@projects.size
+ end
+
+ def self.init
+ db = SQL::Database.new.attach_sources
+
+ db.select("SELECT * FROM projects.projects").execute() do |row|
+ @@projects << Project.new(row)
+ end
+
+ db.close
+ end
+
+ def self.get(id)
+ @@projects.select{ |p| p.id == id }[0]
+ end
+
+ def initialize(row)
+ @@attrs.each do |s|
+ instance_variable_set("@#{s}", row[s.to_s])
+ end
+ end
+
+end
diff --git a/web/lib/ui/projects.rb b/web/lib/ui/projects.rb
new file mode 100644
index 0000000..b2eec53
--- /dev/null
+++ b/web/lib/ui/projects.rb
@@ -0,0 +1,31 @@
+# web/lib/ui/projects.rb
+class Taginfo < Sinatra::Base
+
+ get '/projects' do
+ @title = t.taginfo.projects
+ javascript_for(:flexigrid)
+ javascript "#{ r18n.locale.code }/projects"
+ erb :projects
+ end
+
+ get %r{^/projects/(.*)} do |project|
+ if params[:project].nil?
+ @project_id = project
+ else
+ @project_id = params[:project]
+ end
+
+ @project = Project.get(@project_id)
+
+ if @project
+ @title = [h(@project.name), t.taginfo.projects]
+ end
+
+ section :projects
+
+ javascript_for(:flexigrid)
+ javascript "#{ r18n.locale.code }/project"
+ erb :project
+ end
+
+end
diff --git a/web/lib/ui/taginfo.rb b/web/lib/ui/taginfo.rb
index 2d3d6e6..710f48f 100644
--- a/web/lib/ui/taginfo.rb
+++ b/web/lib/ui/taginfo.rb
@@ -106,4 +106,11 @@ class Taginfo < Sinatra::Base
erb :'taginfo/apidoc'
end
+ get '/taginfo/projects' do
+ @title = t.taginfo.projects
+ @section = 'taginfo'
+ @section_title = t.taginfo.meta
+ erb :'taginfo/projects'
+ end
+
end
diff --git a/web/public/css/taginfo.css b/web/public/css/taginfo.css
index a5bae87..797074f 100644
--- a/web/public/css/taginfo.css
+++ b/web/public/css/taginfo.css
@@ -558,7 +558,7 @@ table.drilldown td#feature {
/* ========== */
table.desc {
- background-color: #b8b8b0;
+ background-color: #ddddd4;
border-radius: 4px;
padding: 6px;
width: 100%;
@@ -574,8 +574,9 @@ table.desc > tbody > tr > th {
table.desc > tbody > tr > td {
vertical-align: top;
- background-color: #e8e8e4;
+ background-color: #f8f8f8;
padding: 2px 4px;
+ border-radius: 1px;
}
table.apiresults {
diff --git a/web/public/img/sources/projects.16.png b/web/public/img/sources/projects.16.png
new file mode 100644
index 0000000..205216d
--- /dev/null
+++ b/web/public/img/sources/projects.16.png
Binary files differ
diff --git a/web/public/img/sources/projects.24.png b/web/public/img/sources/projects.24.png
new file mode 100644
index 0000000..c959426
--- /dev/null
+++ b/web/public/img/sources/projects.24.png
Binary files differ
diff --git a/web/public/img/sources/projects.32.png b/web/public/img/sources/projects.32.png
new file mode 100644
index 0000000..4759626
--- /dev/null
+++ b/web/public/img/sources/projects.32.png
Binary files differ
diff --git a/web/public/img/sources/projects.48.png b/web/public/img/sources/projects.48.png
new file mode 100644
index 0000000..ff82029
--- /dev/null
+++ b/web/public/img/sources/projects.48.png
Binary files differ
diff --git a/web/public/js/taginfo.js b/web/public/js/taginfo.js
index 23a0ad7..88f3745 100644
--- a/web/public/js/taginfo.js
+++ b/web/public/js/taginfo.js
@@ -73,6 +73,10 @@ function url_for_rtype(rtype) {
}
}
+function url_for_project(id) {
+ return '/projects/' + encodeURIComponent(id);
+}
+
function url_for_wiki(title, options) {
var path = '//wiki.openstreetmap.org/';
if (options && options.edit) {
@@ -193,6 +197,14 @@ function link_to_rtype(rtype, attr) {
);
}
+function link_to_project(id, name, attr) {
+ return /*img({ src: '/api/v4/project/icon?project=' + id, alt: '' }) + ' ' +*/ link(
+ url_for_project(id),
+ html_escape(name),
+ attr
+ );
+}
+
function link_to_wiki(title, options) {
if (title == '') {
return '';
@@ -205,6 +217,14 @@ function link_to_wiki(title, options) {
);
}
+function link_to_url(url) {
+ return link(
+ encodeURI(url),
+ html_escape(url.replace(/^http:\/\//, '')),
+ { target: '_blank', 'class': 'extlink' }
+ );
+}
+
/* ============================ */
function html_escape(text) {
@@ -685,6 +705,21 @@ function comparison_list_change(key, value) {
return false;
}
+/* ============================ */
+
+function project_tag_desc(description, icon, url) {
+ var out = '';
+ if (icon) {
+ out += img({src: icon, alt: '', width: 16, height: 16}) + ' ';
+ }
+ if (description) {
+ out += html_escape(description) + ' ';
+ }
+ if (url) {
+ out += '[' + link(url, 'More...', { target: '_blank', 'class': 'extlink' }) + ']'
+ }
+ return out;
+}
/* ============================ */
@@ -758,6 +793,9 @@ jQuery(document).ready(function() {
case 75: // k
window.location = '/keys';
break;
+ case 80: // p
+ window.location = '/projects';
+ break;
case 82: // r
window.location = '/relations';
break;
diff --git a/web/taginfo.rb b/web/taginfo.rb
index 5ad8b66..58a7fe9 100755
--- a/web/taginfo.rb
+++ b/web/taginfo.rb
@@ -53,6 +53,7 @@ require 'lib/language.rb'
require 'lib/sql.rb'
require 'lib/sources.rb'
require 'lib/reports.rb'
+require 'lib/projects.rb'
require 'lib/api.rb'
require 'lib/langtag/bcp47.rb'
@@ -63,6 +64,7 @@ TaginfoConfig.read
#------------------------------------------------------------------------------
DATA_UNTIL = SQL::Database.init('../../data');
+Project.init
class Taginfo < Sinatra::Base
@@ -204,6 +206,8 @@ class Taginfo < Sinatra::Base
load 'lib/api/v4/josm.rb'
load 'lib/api/v4/key.rb'
load 'lib/api/v4/keys.rb'
+ load 'lib/api/v4/project.rb'
+ load 'lib/api/v4/projects.rb'
load 'lib/api/v4/relation.rb'
load 'lib/api/v4/relations.rb'
load 'lib/api/v4/search.rb'
@@ -220,6 +224,7 @@ class Taginfo < Sinatra::Base
load 'lib/ui/embed.rb'
load 'lib/ui/help.rb'
load 'lib/ui/keys.rb'
+ load 'lib/ui/projects.rb'
load 'lib/ui/relation.rb'
load 'lib/ui/reports.rb'
load 'lib/ui/search.rb'
diff --git a/web/views/key.erb b/web/views/key.erb
index 7e51f31..91c79fa 100644
--- a/web/views/key.erb
+++ b/web/views/key.erb
@@ -41,6 +41,7 @@
<li><a href="#map"><%= h(t.taginfo.map) %></a></li>
<li><a href="#wiki"><%= h(t.sources.wiki.name) %></a></li>
<li><a href="#josm"><%= h(t.sources.josm.name) %></a></li>
+ <li><a href="#projects"><%= h(t.taginfo.projects) %></a></li>
</ul>
<div id="overview">
<div style="float: right; text-align: center; padding-left: 20px;">
@@ -116,6 +117,11 @@
<p class="empty"><%= h(t.pages.key.josm.no_styles) %></p>
<% end %>
</div>
+ <div id="projects">
+ <h2><%= h(t.pages.key.projects.title) %></h2>
+ <table id="grid-projects">
+ </table>
+ </div>
</div>
<iframe id="josmiframe" name="josmiframe"></iframe>
<% javascript do
diff --git a/web/views/project.erb b/web/views/project.erb
new file mode 100644
index 0000000..0b7dea4
--- /dev/null
+++ b/web/views/project.erb
@@ -0,0 +1,46 @@
+<div class="pre">
+ <h1><%= h(@project.name) %></h1>
+ <p><%= h(@project.description) %></p>
+</div>
+<div id="tabs">
+ <ul class="no-print">
+ <li><a href="#overview"><%= h(t.taginfo.overview) %></a></li>
+ <li><a href="#tags"><%= h(t.osm.tags) %></a></li>
+ </ul>
+ <div id="overview">
+ <table class="desc">
+ <tr><th><%= h(t.pages.project.overview.project_name) %>:</th><td><%= h(@project.name) %></td></tr>
+ <tr><th><%= h(t.pages.project.overview.project_url) %>:</th><td id="project_url"></td></tr>
+ <tr><th><%= h(t.pages.project.overview.description) %>:</th><td><%= h(@project.description) %></td></tr>
+<% if @project.doc_url %>
+ <tr><th><%= h(t.pages.project.overview.documentation_url) %>:</th><td id="doc_url"></td></tr>
+<% end %>
+ <tr><th><%= h(t.pages.project.overview.last_update) %>:</th><td><%= h(@project.data_updated) %></td></tr>
+ </table>
+ </div>
+ <div id="tags">
+ <h2><%= h(t.pages.project.tags.title) %></h2>
+ <p><%= h(t.pages.project.tags.intro) %></p>
+ <table id="grid-tags">
+ </table>
+ </div>
+</div>
+<% javascript do
+ JS.raw(<<"JAVASCRIPT")
+function page_init2() {
+ var project = #{ @project_id.to_json },
+ project_url = #{ @project.project_url.to_json },
+ doc_url = #{ @project.doc_url.to_json };
+
+ if (project_url) {
+ jQuery('#project_url').html(link_to_url(project_url));
+ }
+ if (doc_url) {
+ jQuery('#doc_url').html(link_to_url(doc_url));
+ }
+
+ init_tabs([project]);
+}
+JAVASCRIPT
+end
+%>
diff --git a/web/views/projects.erb b/web/views/projects.erb
new file mode 100644
index 0000000..ec95947
--- /dev/null
+++ b/web/views/projects.erb
@@ -0,0 +1,8 @@
+<div class="pre">
+ <h1 class="section"><%= h(t.taginfo.projects) %></h1>
+ <p><%= h(t.pages.projects.intro) %></p>
+</div>
+<div class="box resize">
+ <table id="grid-projects">
+ </table>
+</div>
diff --git a/web/views/tag.erb b/web/views/tag.erb
index 1ae5274..de9453c 100644
--- a/web/views/tag.erb
+++ b/web/views/tag.erb
@@ -40,6 +40,7 @@
<li><a href="#map"><%= h(t.taginfo.map) %></a></li>
<li><a href="#wiki"><%= h(t.sources.wiki.name) %></a></li>
<li><a href="#josm"><%= h(t.sources.josm.name) %></a></li>
+ <li><a href="#projects"><%= h(t.taginfo.projects) %></a></li>
</ul>
<div id="overview">
<% if @image_url %>
@@ -113,6 +114,11 @@
<p class="empty"><%= h(t.pages.key.josm.no_styles) %></p>
<% end %>
</div>
+ <div id="projects">
+ <h2><%= h(t.pages.tag.projects.title) %></h2>
+ <table id="grid-projects">
+ </table>
+ </div>
</div>
<iframe id="josmiframe" name="josmiframe"></iframe>
<% javascript do
diff --git a/web/views/taginfo/index.erb b/web/views/taginfo/index.erb
index 81d3862..3139642 100644
--- a/web/views/taginfo/index.erb
+++ b/web/views/taginfo/index.erb
@@ -9,6 +9,7 @@
<li><a href="/taginfo/translations">Translations Overview</a></li>
<li><a href="/taginfo/i18n">Translated Texts</a></li>
<li><a href="/taginfo/config">Configuration</a></li>
+ <li><a href="/taginfo/projects">Projects</a></li>
</ul>
<h2>Software Version</h2>
<p><%= @commit %></p>
diff --git a/web/views/taginfo/projects.erb b/web/views/taginfo/projects.erb
new file mode 100644
index 0000000..dd07ed6
--- /dev/null
+++ b/web/views/taginfo/projects.erb
@@ -0,0 +1,40 @@
+<h1 class="section">Projects</h1>
+
+<table class="list">
+ <tr>
+ <th>Icon</th>
+ <th>Project ID<br/>Project Name</th>
+ <th>Fetch Date<br/>Updated</th><th>Code</th><th>Res</th>
+ <th>JSON URL<br/>Data URL</th><th>Fmt<br/>Vers</th>
+ <th>Project URL<br/>Doc URL</th><th>Contact</th>
+ <th>Description</th>
+ </tr>
+<% Project.each_with_index do |project, n| c = (n%2!=0) ? ' even' : '' %>
+ <tr>
+ <td class="tc<%= c %> nowrap">
+ <img src="<%= h(project.icon_url) %>" width="16" height="16" alt=""/>
+ </td>
+ <td class="<%= c %> nowrap">
+ <a href="/projects/<%= h(project.id) %>"><%= h(project.id) %></a><br/>
+ <%= h(project.name) %>
+ </td>
+ <td class="<%= c %> nowrap">
+ <%= h(project.fetch_date) %><br/>
+ <%= h(project.data_updated) %>
+ </td>
+ <td class="tc<%= c %> nowrap"><%= h(project.fetch_status) %></td>
+ <td class="tc<%= c %> nowrap"><%= h(project.fetch_result) %></td>
+ <td class="<%= c %> nowrap">
+ <a href="<%= h(project.json_url) %>"><%= h(project.json_url) %></a><br/>
+ <a href="<%= h(project.data_url) %>"><%= h(project.data_url) %></a>
+ </td>
+ <td class="tc<%= c %> nowrap"><%= h(project.data_format) %></td>
+ <td class="<%= c %> nowrap">
+ <a href="<%= h(project.project_url) %>"><%= h(project.project_url) %></a><br/>
+ <a href="<%= h(project.doc_url) %>"><%= h(project.doc_url) %></a>
+ </td>
+ <td class="<%= c %> nowrap"><%= h(project.contact_name) %><br/><%= h(project.contact_email) %></td>
+ <td class="<%= c %>"><%= h(project.description) %></td>
+ </tr>
+<% end %>
+</table>
diff --git a/web/viewsjs/key.js.erb b/web/viewsjs/key.js.erb
index f40af36..ad9937d 100644
--- a/web/viewsjs/key.js.erb
+++ b/web/viewsjs/key.js.erb
@@ -1,6 +1,7 @@
<%
osm = @trans.t.osm
misc = @trans.t.misc
+ taginfo = @trans.t.taginfo
page = @trans.t.pages.key
%>
var create_flexigrid_for = {
@@ -143,6 +144,31 @@ var create_flexigrid_for = {
return data;
}
});
+ },
+ projects: function(key, filter_type) {
+ create_flexigrid('grid-projects', {
+ url: '/api/4/tag/projects?key=' + encodeURIComponent(key),
+ colModel: [
+ { display: '<%= h(taginfo.project) %>', name: 'project_name', width: 200, sortable: true },
+ { display: '<%= h(osm.tag) %>', name: 'key', width: 220, sortable: true },
+ { display: '<%= h(misc.description) %>', name: 'description', width: 600, sortable: false, align: 'left' }
+ ],
+ searchitems: [
+ { display: '<%= h(taginfo.project) %>/<%= h(osm.value) %>', name: 'project_value' }
+ ],
+ sortname: 'key',
+ sortorder: 'asc',
+ preProcess: function(data) {
+ data.rows = jQuery.map(data.data, function(row, i) {
+ return { 'cell': [
+ link_to_project(row.project_id, row.project_name),
+ row.value ? link_to_tag(row.key, row.value) : (link_to_key(row.key) + '=*'),
+ project_tag_desc(row.description, row.icon_url, row.doc_url)
+ ] };
+ });
+ return data;
+ }
+ });
}
};
diff --git a/web/viewsjs/project.js.erb b/web/viewsjs/project.js.erb
new file mode 100644
index 0000000..59af6dd
--- /dev/null
+++ b/web/viewsjs/project.js.erb
@@ -0,0 +1,35 @@
+<%
+ osm = @trans.t.osm
+ misc = @trans.t.misc
+ %>
+var create_flexigrid_for = {
+ tags: function(project) {
+ create_flexigrid('grid-tags', {
+ url: '/api/4/project/tags?project=' + encodeURIComponent(project),
+ colModel: [
+ { display: '<%= h(osm.tag) %>', name: 'tag', width: 260, sortable: true },
+ { display: '<%= h(misc.description) %>', name: 'description', width: 800, sortable: false, align: 'left' }
+ ],
+ searchitems: [
+ { display: '<%= h(osm.key) %>/<%= h(osm.value) %>', name: 'key_value' }
+ ],
+ sortname: 'tag',
+ sortorder: 'asc',
+ preProcess: function(data) {
+ data.rows = jQuery.map(data.data, function(row, i) {
+ return { 'cell': [
+ row.value ? link_to_tag(row.key, row.value) : (link_to_key(row.key) + '=*'),
+ project_tag_desc(row.description, row.doc_url, row.icon_url)
+ ] };
+ });
+ delete data.data;
+ return data;
+ }
+ });
+ }
+};
+
+function page_init() {
+ up = function() { window.location = '/projects'; }
+ page_init2();
+}
diff --git a/web/viewsjs/projects.js.erb b/web/viewsjs/projects.js.erb
new file mode 100644
index 0000000..55878c9
--- /dev/null
+++ b/web/viewsjs/projects.js.erb
@@ -0,0 +1,23 @@
+function page_init() {
+ create_flexigrid('grid-projects', {
+ url: '/api/4/projects/all',
+ colModel: [
+ { display: '<%= h(@trans.t.taginfo.project) %>', name: 'name', width: 300, sortable: true },
+ { display: '<%= h(@trans.t.misc.description) %>', name: 'description', width: 600, sortable: false }
+ ],
+ searchitems: [
+ { display: '<%= h(@trans.t.taginfo.project) %>/<%= h(@trans.t.misc.description) %>', name: 'name' }
+ ],
+ sortname: 'name',
+ sortorder: 'asc',
+ preProcess: function(data) {
+ data.rows = jQuery.map(data.data, function(row, i) {
+ return { 'cell': [
+ link_to_project(row.id, row.name),
+ html_escape(row.description)
+ ] };
+ });
+ return data;
+ }
+ });
+}
diff --git a/web/viewsjs/tag.js.erb b/web/viewsjs/tag.js.erb
index f9181d4..d47906e 100644
--- a/web/viewsjs/tag.js.erb
+++ b/web/viewsjs/tag.js.erb
@@ -1,6 +1,7 @@
<%
osm = @trans.t.osm
misc = @trans.t.misc
+ taginfo = @trans.t.taginfo
page = @trans.t.pages.tag
%>
function link_to_key_or_tag(key, value) {
@@ -123,6 +124,31 @@ var create_flexigrid_for = {
return data;
}
});
+ },
+ projects: function(key, value) {
+ create_flexigrid('grid-projects', {
+ url: '/api/4/tag/projects?key=' + encodeURIComponent(key) + '&value=' + encodeURIComponent(value),
+ colModel: [
+ { display: '<%= h(taginfo.project) %>', name: 'project_name', width: 200, sortable: true },
+ { display: '<%= h(osm.tag) %>', name: 'key', width: 220, sortable: true },
+ { display: '<%= h(misc.description) %>', name: 'description', width: 600, sortable: false, align: 'left' }
+ ],
+ searchitems: [
+ { display: '<%= h(taginfo.project) %>/<%= h(osm.value) %>', name: 'project_value' }
+ ],
+ sortname: 'key',
+ sortorder: 'asc',
+ preProcess: function(data) {
+ data.rows = jQuery.map(data.data, function(row, i) {
+ return { 'cell': [
+ link_to_project(row.project_id, row.project_name),
+ row.value ? link_to_tag(row.key, row.value) : (link_to_key(row.key) + '=*'),
+ project_tag_desc(row.description, row.icon_url, row.doc_url)
+ ] };
+ });
+ return data;
+ }
+ });
}
};