2012-03-03 16:28:40 +01:00
#!/usr/bin/perl
# Copyright 2011 Blars Blarson
# Released under GPL version 2
package IkiWiki::Plugin::osm ;
use utf8 ;
use strict ;
use warnings ;
use IkiWiki 3.0 ;
sub import {
2012-03-03 17:16:00 +01:00
add_underlay ( "osm" ) ;
2012-03-03 17:05:04 +01:00
hook ( type = > "getsetup" , id = > "osm" , call = > \ & getsetup ) ;
hook ( type = > "format" , id = > "osm" , call = > \ & format ) ;
hook ( type = > "preprocess" , id = > "osm" , call = > \ & preprocess ) ;
hook ( type = > "preprocess" , id = > "waypoint" , call = > \ & process_waypoint ) ;
2017-06-21 00:36:21 +02:00
hook ( type = > "changes" , id = > "waypoint" , call = > \ & changes ) ;
2012-03-03 17:05:04 +01:00
hook ( type = > "cgi" , id = > "osm" , call = > \ & cgi ) ;
2012-03-03 16:28:40 +01:00
}
sub getsetup () {
2012-03-03 17:05:04 +01:00
return
plugin = > {
safe = > 1 ,
rebuild = > 1 ,
section = > "special-purpose" ,
} ,
osm_default_zoom = > {
type = > "integer" ,
example = > "15" ,
description = > "the default zoom when you click on the map link" ,
safe = > 1 ,
rebuild = > 1 ,
} ,
osm_default_icon = > {
type = > "string" ,
2012-03-13 22:35:06 +01:00
example = > "ikiwiki/images/osm.png" ,
description = > "the icon shown on links and on the main map" ,
2012-03-03 17:05:04 +01:00
safe = > 0 ,
rebuild = > 1 ,
} ,
osm_alt = > {
type = > "string" ,
example = > "" ,
description = > "the alt tag of links, defaults to empty" ,
safe = > 0 ,
rebuild = > 1 ,
} ,
osm_format = > {
type = > "string" ,
example = > "KML" ,
description = > "the output format for waypoints, can be KML, GeoJSON or CSV (one or many, comma-separated)" ,
safe = > 1 ,
rebuild = > 1 ,
} ,
osm_tag_default_icon = > {
type = > "string" ,
example = > "icon.png" ,
2012-03-13 22:35:06 +01:00
description = > "the icon attached to a tag, displayed on the map for tagged pages" ,
2012-03-03 17:05:04 +01:00
safe = > 0 ,
rebuild = > 1 ,
} ,
2012-08-03 03:10:42 +02:00
osm_openlayers_url = > {
type = > "string" ,
example = > "http://www.openlayers.org/api/OpenLayers.js" ,
description = > "Url for the OpenLayers.js file" ,
safe = > 0 ,
rebuild = > 1 ,
} ,
2012-08-24 21:55:28 +02:00
osm_layers = > {
2012-08-07 05:00:31 +02:00
type = > "string" ,
2012-08-25 16:13:04 +02:00
example = > { 'OSM' , 'GoogleSatellite' } ,
2012-08-25 14:53:30 +02:00
description = > "Layers to use in the map. Can be either the 'OSM' string or a type option for Google maps (GoogleNormal, GoogleSatellite, GoogleHybrid or GooglePhysical). It can also be an arbitrary URL in a syntax acceptable for OpenLayers.Layer.OSM.url parameter." ,
2012-08-07 05:00:31 +02:00
safe = > 0 ,
rebuild = > 1 ,
} ,
2012-08-09 07:07:20 +02:00
osm_google_apikey = > {
type = > "string" ,
example = > "" ,
description = > "Google maps API key, Google layer not used if missing, see https://code.google.com/apis/console/ to get an API key" ,
safe = > 1 ,
rebuild = > 1 ,
} ,
2012-03-03 16:28:40 +01:00
}
2012-08-02 22:29:32 +02:00
sub register_rendered_files {
my $ map = shift ;
my $ page = shift ;
my $ dest = shift ;
if ( $ page eq $ dest ) {
my % formats = get_formats ( ) ;
if ( $ formats { 'GeoJSON' } ) {
will_render ( $ page , "$map/pois.json" ) ;
}
if ( $ formats { 'CSV' } ) {
will_render ( $ page , "$map/pois.txt" ) ;
}
if ( $ formats { 'KML' } ) {
will_render ( $ page , "$map/pois.kml" ) ;
}
}
}
2012-03-03 16:28:40 +01:00
sub preprocess {
2012-03-03 17:05:04 +01:00
my % params = @ _ ;
2012-03-19 00:33:11 +01:00
my $ page = $ params { page } ;
my $ dest = $ params { destpage } ;
my $ loc = $ params { loc } ; # sanitized below
my $ lat = $ params { lat } ; # sanitized below
my $ lon = $ params { lon } ; # sanitized below
my $ href = $ params { href } ;
2012-03-03 17:05:04 +01:00
my ( $ width , $ height , $ float ) ;
2012-03-18 23:02:03 +01:00
$ height = scrub ( $ params { 'height' } || "300px" , $ page , $ dest ) ; # sanitized here
$ width = scrub ( $ params { 'width' } || "500px" , $ page , $ dest ) ; # sanitized here
$ float = ( defined ( $ params { 'right' } ) && 'right' ) || ( defined ( $ params { 'left' } ) && 'left' ) ; # sanitized here
2012-03-03 17:05:04 +01:00
my $ zoom = scrub ( $ params { 'zoom' } // $ config { 'osm_default_zoom' } // 15 , $ page , $ dest ) ; # sanitized below
my $ map ;
2012-03-18 23:02:03 +01:00
$ map = $ params { 'map' } || 'map' ;
2012-03-03 17:05:04 +01:00
$ map = scrub ( $ map , $ page , $ dest ) ; # sanitized here
my $ name = scrub ( $ params { 'name' } || $ map , $ page , $ dest ) ;
if ( defined ( $ lon ) || defined ( $ lat ) || defined ( $ loc ) ) {
( $ lon , $ lat ) = scrub_lonlat ( $ loc , $ lon , $ lat ) ;
}
if ( $ zoom !~ /^\d\d?$/ || $ zoom < 2 || $ zoom > 18 ) {
error ( "Bad zoom" ) ;
}
2012-03-18 22:39:06 +01:00
if ( ! defined $ href || ! length $ href ) {
$ href = IkiWiki:: cgiurl (
do = > "osm" ,
map = > $ map ,
) ;
}
2012-08-02 22:29:32 +02:00
register_rendered_files ( $ map , $ page , $ dest ) ;
2012-03-03 17:05:04 +01:00
$ pagestate { $ page } { 'osm' } { $ map } { 'displays' } { $ name } = {
height = > $ height ,
width = > $ width ,
float = > $ float ,
zoom = > $ zoom ,
2012-03-18 23:02:03 +01:00
fullscreen = > 0 ,
2012-03-03 17:05:04 +01:00
editable = > defined ( $ params { 'editable' } ) ,
lat = > $ lat ,
lon = > $ lon ,
href = > $ href ,
2012-08-09 07:07:20 +02:00
google_apikey = > $ config { 'osm_google_apikey' } ,
2012-03-03 17:05:04 +01:00
} ;
return "<div id=\"mapdiv-$name\"></div>" ;
2012-03-03 16:28:40 +01:00
}
sub process_waypoint {
2012-03-03 17:05:04 +01:00
my % params = @ _ ;
my $ loc = $ params { 'loc' } ; # sanitized below
my $ lat = $ params { 'lat' } ; # sanitized below
my $ lon = $ params { 'lon' } ; # sanitized below
my $ page = $ params { 'page' } ; # not sanitized?
my $ dest = $ params { 'destpage' } ; # not sanitized?
my $ hidden = defined ( $ params { 'hidden' } ) ; # sanitized here
my ( $ p ) = $ page =~ /(?:^|\/)([^\/]+)\/?$/ ; # shorter page name
my $ name = scrub ( $ params { 'name' } || $ p , $ page , $ dest ) ; # sanitized here
my $ desc = scrub ( $ params { 'desc' } || '' , $ page , $ dest ) ; # sanitized here
my $ zoom = scrub ( $ params { 'zoom' } // $ config { 'osm_default_zoom' } // 15 , $ page , $ dest ) ; # sanitized below
2012-03-13 22:35:06 +01:00
my $ icon = $ config { 'osm_default_icon' } || "ikiwiki/images/osm.png" ; # sanitized: we trust $config
2012-03-03 17:05:04 +01:00
my $ map = scrub ( $ params { 'map' } || 'map' , $ page , $ dest ) ; # sanitized here
my $ alt = $ config { 'osm_alt' } ? "alt=\"$config{'osm_alt'}\"" : '' ; # sanitized: we trust $config
if ( $ zoom !~ /^\d\d?$/ || $ zoom < 2 || $ zoom > 18 ) {
error ( "Bad zoom" ) ;
}
( $ lon , $ lat ) = scrub_lonlat ( $ loc , $ lon , $ lat ) ;
if ( ! defined ( $ lat ) || ! defined ( $ lon ) ) {
error ( "Must specify lat and lon" ) ;
}
my $ tag = $ params { 'tag' } ;
2012-03-13 22:35:06 +01:00
foreach my $ t ( keys % { $ typedlinks { $ page } { 'tag' } } ) {
if ( $ icon = get_tag_icon ( $ t ) ) {
$ tag = $ t ;
last ;
2012-03-03 17:05:04 +01:00
}
2012-03-13 22:35:06 +01:00
$ t =~ s!/$config{'tagbase'}/!! ;
if ( $ icon = get_tag_icon ( $ t ) ) {
$ tag = $ t ;
last ;
2012-03-03 17:05:04 +01:00
}
}
2012-03-13 22:49:41 +01:00
$ icon = urlto ( $ icon , $ dest , 1 ) ;
2013-06-23 20:14:52 +02:00
$ icon =~ s!/*$!! ; # hack - urlto shouldn't be appending a slash in the first place
2012-03-03 17:05:04 +01:00
$ tag = '' unless $ tag ;
2012-08-02 22:29:32 +02:00
register_rendered_files ( $ map , $ page , $ dest ) ;
2012-03-03 17:05:04 +01:00
$ pagestate { $ page } { 'osm' } { $ map } { 'waypoints' } { $ name } = {
page = > $ page ,
desc = > $ desc ,
icon = > $ icon ,
tag = > $ tag ,
lat = > $ lat ,
lon = > $ lon ,
2012-03-18 22:48:09 +01:00
# How to link back to the page from the map, not to be
2012-03-03 17:05:04 +01:00
# confused with the URL of the map itself sent to the
2012-03-18 22:48:09 +01:00
# embeded map below. Note: used in generated KML etc file,
# so must be absolute.
href = > urlto ( $ page ) ,
2012-03-03 17:05:04 +01:00
} ;
2012-03-19 00:33:11 +01:00
my $ mapurl = IkiWiki:: cgiurl (
do = > "osm" ,
map = > $ map ,
lat = > $ lat ,
lon = > $ lon ,
zoom = > $ zoom ,
) ;
2012-03-03 17:05:04 +01:00
my $ output = '' ;
if ( defined ( $ params { 'embed' } ) ) {
2012-03-19 00:33:11 +01:00
$ output . = preprocess ( % params ,
href = > $ mapurl ,
) ;
2012-03-03 17:05:04 +01:00
}
if ( ! $ hidden ) {
2012-03-19 00:33:11 +01:00
$ output . = "<a href=\"$mapurl\"><img class=\"img\" src=\"$icon\" $alt /></a>" ;
2012-03-03 17:05:04 +01:00
}
return $ output ;
2012-03-03 16:28:40 +01:00
}
# get the icon from the given tag
sub get_tag_icon ($) {
2012-03-03 17:05:04 +01:00
my $ tag = shift ;
# look for an icon attached to the tag
my $ attached = $ tag . '/' . $ config { 'osm_tag_default_icon' } ;
2018-04-24 04:28:49 +02:00
if ( srcfile ( $ attached , 1 ) ) {
2012-03-03 17:05:04 +01:00
return $ attached ;
}
else {
return undef ;
}
2012-03-03 16:28:40 +01:00
}
sub scrub_lonlat ($$$) {
2012-03-03 17:05:04 +01:00
my ( $ loc , $ lon , $ lat ) = @ _ ;
if ( $ loc ) {
if ( $ loc =~ /^\s*(\-?\d+(?:\.\d*°?|(?:°?|\s)\s*\d+(?:\.\d*\'?|(?:\'|\s)\s*\d+(?:\.\d*)?\"?|\'?)°?)[NS]?)\s*\,?\;?\s*(\-?\d+(?:\.\d*°?|(?:°?|\s)\s*\d+(?:\.\d*\'?|(?:\'|\s)\s*\d+(?:\.\d*)?\"?|\'?)°?)[EW]?)\s*$/ ) {
$ lat = $ 1 ;
$ lon = $ 2 ;
}
else {
error ( "Bad loc" ) ;
}
}
if ( defined ( $ lat ) ) {
if ( $ lat =~ /^(\-?)(\d+)(?:(\.\d*)°?|(?:°|\s)\s*(\d+)(?:(\.\d*)\'?|(?:\'|\s)\s*(\d+(?:\.\d*)?\"?)|\'?)|°?)\s*([NS])?\s*$/ ) {
$ lat = $ 2 + ( $ 3 // 0 ) + ( ( ( $ 4 // 0 ) + ( ( $ 5 // 0 ) + ( ( $ 6 // 0 ) /60.)))/ 60 . ) ;
if ( ( $ 1 eq '-' ) || ( ( $ 7 // '' ) eq 'S' ) ) {
$ lat = - $ lat ;
}
}
else {
error ( "Bad lat" ) ;
}
}
if ( defined ( $ lon ) ) {
if ( $ lon =~ /^(\-?)(\d+)(?:(\.\d*)°?|(?:°|\s)\s*(\d+)(?:(\.\d*)\'?|(?:\'|\s)\s*(\d+(?:\.\d*)?\"?)|\'?)|°?)\s*([EW])?$/ ) {
$ lon = $ 2 + ( $ 3 // 0 ) + ( ( ( $ 4 // 0 ) + ( ( $ 5 // 0 ) + ( ( $ 6 // 0 ) /60.)))/ 60 . ) ;
if ( ( $ 1 eq '-' ) || ( ( $ 7 // '' ) eq 'W' ) ) {
$ lon = - $ lon ;
}
}
else {
error ( "Bad lon" ) ;
}
}
if ( $ lat < - 90 || $ lat > 90 || $ lon < - 180 || $ lon > 180 ) {
error ( "Location out of range" ) ;
}
return ( $ lon , $ lat ) ;
2012-03-03 16:28:40 +01:00
}
2017-06-21 00:36:21 +02:00
sub changes {
2012-03-03 17:05:04 +01:00
my % waypoints = ( ) ;
my % linestrings = ( ) ;
foreach my $ page ( keys % pagestate ) {
if ( exists $ pagestate { $ page } { 'osm' } ) {
foreach my $ map ( keys % { $ pagestate { $ page } { 'osm' } } ) {
foreach my $ name ( keys % { $ pagestate { $ page } { 'osm' } { $ map } { 'waypoints' } } ) {
debug ( "found waypoint $name" ) ;
$ waypoints { $ map } { $ name } = $ pagestate { $ page } { 'osm' } { $ map } { 'waypoints' } { $ name } ;
}
}
}
}
foreach my $ page ( keys % pagestate ) {
if ( exists $ pagestate { $ page } { 'osm' } ) {
foreach my $ map ( keys % { $ pagestate { $ page } { 'osm' } } ) {
# examine the links on this page
foreach my $ name ( keys % { $ pagestate { $ page } { 'osm' } { $ map } { 'waypoints' } } ) {
if ( exists $ links { $ page } ) {
foreach my $ otherpage ( @ { $ links { $ page } } ) {
if ( exists $ waypoints { $ map } { $ otherpage } ) {
push ( @ { $ linestrings { $ map } } , [
[ $ waypoints { $ map } { $ name } { 'lon' } , $ waypoints { $ map } { $ name } { 'lat' } ] ,
[ $ waypoints { $ map } { $ otherpage } { 'lon' } , $ waypoints { $ map } { $ otherpage } { 'lat' } ]
] ) ;
}
}
}
}
}
# clear the state, it will be regenerated on the next parse
# the idea here is to clear up removed waypoints...
$ pagestate { $ page } { 'osm' } = ( ) ;
}
}
2012-03-18 22:07:01 +01:00
my % formats = get_formats ( ) ;
2012-03-03 17:05:04 +01:00
if ( $ formats { 'GeoJSON' } ) {
writejson ( \ % waypoints , \ % linestrings ) ;
}
if ( $ formats { 'CSV' } ) {
writecsvs ( \ % waypoints , \ % linestrings ) ;
}
if ( $ formats { 'KML' } ) {
writekml ( \ % waypoints , \ % linestrings ) ;
}
2012-03-03 16:28:40 +01:00
}
sub writejson ($;$) {
2012-03-03 17:05:04 +01:00
my % waypoints = % { $ _ [ 0 ] } ;
my % linestrings = % { $ _ [ 1 ] } ;
eval q{ use JSON } ;
error $@ if $@ ;
foreach my $ map ( keys % waypoints ) {
my % geojson = ( "type" = > "FeatureCollection" , "features" = > [] ) ;
foreach my $ name ( keys % { $ waypoints { $ map } } ) {
my % marker = ( "type" = > "Feature" ,
"geometry" = > { "type" = > "Point" , "coordinates" = > [ $ waypoints { $ map } { $ name } { 'lon' } , $ waypoints { $ map } { $ name } { 'lat' } ] } ,
"properties" = > $ waypoints { $ map } { $ name } ) ;
push @ { $ geojson { 'features' } } , \ % marker ;
}
foreach my $ linestring ( @ { $ linestrings { $ map } } ) {
my % json = ( "type" = > "Feature" ,
"geometry" = > { "type" = > "LineString" , "coordinates" = > $ linestring } ) ;
push @ { $ geojson { 'features' } } , \ % json ;
}
2012-03-13 22:16:09 +01:00
writefile ( "pois.json" , $ config { destdir } . "/$map" , to_json ( \ % geojson ) ) ;
2012-03-03 17:05:04 +01:00
}
2012-03-03 16:28:40 +01:00
}
sub writekml ($;$) {
2012-03-03 17:05:04 +01:00
my % waypoints = % { $ _ [ 0 ] } ;
my % linestrings = % { $ _ [ 1 ] } ;
eval q{ use XML::Writer } ;
error $@ if $@ ;
foreach my $ map ( keys % waypoints ) {
2012-03-13 22:16:09 +01:00
my $ output ;
my $ writer = XML::Writer - > new ( OUTPUT = > \ $ output ,
2012-08-09 08:04:06 +02:00
DATA_MODE = > 1 , DATA_INDENT = > ' ' , ENCODING = > 'UTF-8' ) ;
2012-03-03 17:05:04 +01:00
$ writer - > xmlDecl ( ) ;
$ writer - > startTag ( "kml" , "xmlns" = > "http://www.opengis.net/kml/2.2" ) ;
2012-08-09 04:23:10 +02:00
$ writer - > startTag ( "Document" ) ;
2012-03-03 17:05:04 +01:00
# first pass: get the icons
2012-08-09 08:03:02 +02:00
my % tags_map = ( ) ; # keep track of tags seen
2012-03-03 17:05:04 +01:00
foreach my $ name ( keys % { $ waypoints { $ map } } ) {
my % options = % { $ waypoints { $ map } { $ name } } ;
2012-08-09 08:03:02 +02:00
if ( ! $ tags_map { $ options { tag } } ) {
debug ( "found new style " . $ options { tag } ) ;
$ tags_map { $ options { tag } } = ( ) ;
$ writer - > startTag ( "Style" , id = > $ options { tag } ) ;
$ writer - > startTag ( "IconStyle" ) ;
$ writer - > startTag ( "Icon" ) ;
$ writer - > startTag ( "href" ) ;
$ writer - > characters ( $ options { icon } ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
}
$ tags_map { $ options { tag } } { $ name } = \ % options ;
2012-03-03 17:05:04 +01:00
}
foreach my $ name ( keys % { $ waypoints { $ map } } ) {
my % options = % { $ waypoints { $ map } { $ name } } ;
$ writer - > startTag ( "Placemark" ) ;
$ writer - > startTag ( "name" ) ;
$ writer - > characters ( $ name ) ;
$ writer - > endTag ( ) ;
$ writer - > startTag ( "styleUrl" ) ;
$ writer - > characters ( '#' . $ options { tag } ) ;
$ writer - > endTag ( ) ;
#$writer->emptyTag('atom:link', href => $options{href});
# to make it easier for us as the atom:link parameter is
# hard to access from javascript
$ writer - > startTag ( 'href' ) ;
$ writer - > characters ( $ options { href } ) ;
$ writer - > endTag ( ) ;
$ writer - > startTag ( "description" ) ;
$ writer - > characters ( $ options { desc } ) ;
$ writer - > endTag ( ) ;
$ writer - > startTag ( "Point" ) ;
$ writer - > startTag ( "coordinates" ) ;
$ writer - > characters ( $ options { lon } . "," . $ options { lat } ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
}
my $ i = 0 ;
foreach my $ linestring ( @ { $ linestrings { $ map } } ) {
$ writer - > startTag ( "Placemark" ) ;
$ writer - > startTag ( "name" ) ;
$ writer - > characters ( "linestring " . $ i + + ) ;
$ writer - > endTag ( ) ;
$ writer - > startTag ( "LineString" ) ;
$ writer - > startTag ( "coordinates" ) ;
my $ str = '' ;
foreach my $ coord ( @ { $ linestring } ) {
$ str . = join ( ',' , @ { $ coord } ) . " \n" ;
}
$ writer - > characters ( $ str ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
$ writer - > endTag ( ) ;
}
$ writer - > endTag ( ) ;
2012-08-09 04:23:10 +02:00
$ writer - > endTag ( ) ;
2012-03-03 17:05:04 +01:00
$ writer - > end ( ) ;
2012-03-13 22:16:09 +01:00
2012-03-18 22:07:01 +01:00
writefile ( "pois.kml" , $ config { destdir } . "/$map" , $ output ) ;
2012-03-03 17:05:04 +01:00
}
2012-03-03 16:28:40 +01:00
}
sub writecsvs ($;$) {
2012-03-03 17:05:04 +01:00
my % waypoints = % { $ _ [ 0 ] } ;
foreach my $ map ( keys % waypoints ) {
my $ poisf = "lat\tlon\ttitle\tdescription\ticon\ticonSize\ticonOffset\n" ;
foreach my $ name ( keys % { $ waypoints { $ map } } ) {
my % options = % { $ waypoints { $ map } { $ name } } ;
my $ line =
$ options { 'lat' } . "\t" .
$ options { 'lon' } . "\t" .
$ name . "\t" .
$ options { 'desc' } . '<br /><a href="' . $ options { 'page' } . '">' . $ name . "</a>\t" .
$ options { 'icon' } . "\n" ;
$ poisf . = $ line ;
}
2012-03-13 22:16:09 +01:00
writefile ( "pois.txt" , $ config { destdir } . "/$map" , $ poisf ) ;
2012-03-03 17:05:04 +01:00
}
2012-03-03 16:28:40 +01:00
}
# pipe some data through the HTML scrubber
#
# code taken from the meta.pm plugin
sub scrub ($$$) {
if ( IkiWiki::Plugin::htmlscrubber - > can ( "sanitize" ) ) {
return IkiWiki::Plugin::htmlscrubber:: sanitize (
content = > shift , page = > shift , destpage = > shift ) ;
}
else {
return shift ;
}
}
# taken from toggle.pm
sub format (@) {
2012-03-03 17:05:04 +01:00
my % params = @ _ ;
if ( $ params { content } =~ m !<div[^>]*id="mapdiv-[^"]*"[^>]*>!g ) {
if ( ! ( $ params { content } =~ s!</body>!include_javascript($params{page})."</body>"!em ) ) {
# no <body> tag, probably in preview mode
$ params { content } = $ params { content } . include_javascript ( $ params { page } ) ;
}
}
return $ params { content } ;
2012-03-03 16:28:40 +01:00
}
2012-03-18 22:07:01 +01:00
sub preferred_format () {
2012-03-03 17:05:04 +01:00
if ( ! defined ( $ config { 'osm_format' } ) || ! $ config { 'osm_format' } ) {
$ config { 'osm_format' } = 'KML' ;
}
my @ spl = split ( /, */ , $ config { 'osm_format' } ) ;
return shift @ spl ;
2012-03-03 16:28:40 +01:00
}
2012-03-18 22:07:01 +01:00
sub get_formats () {
if ( ! defined ( $ config { 'osm_format' } ) || ! $ config { 'osm_format' } ) {
$ config { 'osm_format' } = 'KML' ;
}
map { $ _ = > 1 } split ( /, */ , $ config { 'osm_format' } ) ;
}
2012-03-03 16:28:40 +01:00
sub include_javascript ($) {
2012-03-03 17:05:04 +01:00
my $ page = shift ;
my $ loader ;
if ( exists $ pagestate { $ page } { 'osm' } ) {
foreach my $ map ( keys % { $ pagestate { $ page } { 'osm' } } ) {
foreach my $ name ( keys % { $ pagestate { $ page } { 'osm' } { $ map } { 'displays' } } ) {
2012-03-18 22:07:01 +01:00
$ loader . = map_setup_code ( $ map , $ name , % { $ pagestate { $ page } { 'osm' } { $ map } { 'displays' } { $ name } } ) ;
2012-03-03 17:05:04 +01:00
}
}
}
if ( $ loader ) {
2013-12-03 17:42:04 +01:00
return embed_map_code ( $ page ) . "<script type=\"text/javascript\">$loader</script>" ;
2012-03-03 17:05:04 +01:00
}
else {
return '' ;
}
2012-03-03 16:28:40 +01:00
}
sub cgi ($) {
2012-03-03 17:05:04 +01:00
my $ cgi = shift ;
2012-03-03 16:28:40 +01:00
2012-03-03 17:05:04 +01:00
return unless defined $ cgi - > param ( 'do' ) &&
$ cgi - > param ( "do" ) eq "osm" ;
2012-03-18 20:54:47 +01:00
IkiWiki:: loadindex ( ) ;
2012-03-03 16:28:40 +01:00
2012-03-03 17:05:04 +01:00
IkiWiki:: decode_cgi_utf8 ( $ cgi ) ;
2012-03-03 16:28:40 +01:00
2012-03-03 17:05:04 +01:00
my $ map = $ cgi - > param ( 'map' ) ;
if ( ! defined $ map || $ map !~ /^[a-z]*$/ ) {
error ( "invalid map parameter" ) ;
}
2012-03-03 16:28:40 +01:00
2012-03-03 17:05:04 +01:00
print "Content-Type: text/html\r\n" ;
print ( "\r\n" ) ;
print "<html><body>" ;
print "<div id=\"mapdiv-$map\"></div>" ;
2012-03-03 21:38:01 +01:00
print embed_map_code ( ) ;
2013-12-03 17:42:04 +01:00
print "<script type=\"text/javascript\">" ;
2012-03-18 22:07:01 +01:00
print map_setup_code ( $ map , $ map ,
lat = > "urlParams['lat']" ,
lon = > "urlParams['lon']" ,
zoom = > "urlParams['zoom']" ,
fullscreen = > 1 ,
editable = > 1 ,
2012-08-09 07:07:20 +02:00
google_apikey = > $ config { 'osm_google_apikey' } ,
2012-03-18 22:07:01 +01:00
) ;
print "</script>" ;
2012-03-03 17:05:04 +01:00
print "</body></html>" ;
2012-03-03 16:28:40 +01:00
2012-03-03 17:05:04 +01:00
exit 0 ;
2012-03-03 16:28:40 +01:00
}
2012-03-03 21:38:01 +01:00
sub embed_map_code (;$) {
my $ page = shift ;
2012-08-03 03:10:42 +02:00
my $ olurl = $ config { osm_openlayers_url } || "http://www.openlayers.org/api/OpenLayers.js" ;
2012-08-09 07:07:20 +02:00
my $ code = '<script src="' . $ olurl . '" type="text/javascript" charset="utf-8"></script>' . "\n" .
2012-03-03 21:38:01 +01:00
'<script src="' . urlto ( "ikiwiki/osm.js" , $ page ) .
2012-03-03 21:19:29 +01:00
'" type="text/javascript" charset="utf-8"></script>' . "\n" ;
2012-08-09 07:07:20 +02:00
if ( $ config { 'osm_google_apikey' } ) {
$ code . = '<script src="http://maps.google.com/maps?file=api&v=2&key=' . $ config { 'osm_google_apikey' } . '&sensor=false" type="text/javascript" charset="utf-8"></script>' ;
}
return $ code ;
2012-03-03 16:28:40 +01:00
}
2012-03-18 22:07:01 +01:00
sub map_setup_code ($;@) {
my $ map = shift ;
my $ name = shift ;
my % options = @ _ ;
2012-08-07 05:00:31 +02:00
my $ mapurl = $ config { osm_map_url } ;
2012-03-18 22:07:01 +01:00
eval q{ use JSON } ;
error $@ if $@ ;
$ options { 'format' } = preferred_format ( ) ;
my % formats = get_formats ( ) ;
if ( $ formats { 'GeoJSON' } ) {
$ options { 'jsonurl' } = urlto ( $ map . "/pois.json" ) ;
}
if ( $ formats { 'CSV' } ) {
$ options { 'csvurl' } = urlto ( $ map . "/pois.txt" ) ;
}
if ( $ formats { 'KML' } ) {
$ options { 'kmlurl' } = urlto ( $ map . "/pois.kml" ) ;
}
2012-08-07 05:00:31 +02:00
if ( $ mapurl ) {
$ options { 'mapurl' } = $ mapurl ;
}
2012-08-24 21:55:28 +02:00
$ options { 'layers' } = $ config { osm_layers } ;
2012-08-07 05:00:31 +02:00
2014-01-15 20:53:51 +01:00
$ name =~ s/'//g ; # $name comes from user input
2012-03-18 22:07:01 +01:00
return "mapsetup('mapdiv-$name', " . to_json ( \ % options ) . ");" ;
}
2012-03-03 16:28:40 +01:00
1 ;