diff options
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 Binary files differnew file mode 100644 index 0000000..96b184f --- /dev/null +++ b/projects/id_editor.png 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 Binary files differnew file mode 100644 index 0000000..a08df46 --- /dev/null +++ b/projects/osrm.png 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 Binary files differnew file mode 100644 index 0000000..205216d --- /dev/null +++ b/web/public/img/sources/projects.16.png diff --git a/web/public/img/sources/projects.24.png b/web/public/img/sources/projects.24.png Binary files differnew file mode 100644 index 0000000..c959426 --- /dev/null +++ b/web/public/img/sources/projects.24.png diff --git a/web/public/img/sources/projects.32.png b/web/public/img/sources/projects.32.png Binary files differnew file mode 100644 index 0000000..4759626 --- /dev/null +++ b/web/public/img/sources/projects.32.png diff --git a/web/public/img/sources/projects.48.png b/web/public/img/sources/projects.48.png Binary files differnew file mode 100644 index 0000000..ff82029 --- /dev/null +++ b/web/public/img/sources/projects.48.png 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; + } + }); } }; |