From CruisersWiki
//
/*
features.js
Copyright (c) 2016 Vadim Shlyakhov
Licensed MIT
*/
(function () {
var kmlFormat = new ol.format.KML();
function parsePage (options) {
var parents = [];
function out(poi) {
var feature = new ol.Feature(poi);
feature.getGeometry().transform('EPSG:4326', options.projection);
options.addFeature(feature);
}
function some (arr) {
return typeof arr !== 'undefined' && arr.length > 0;
}
function first (arr) {
return some(arr) ? arr[0] : '';
}
function join (arr) {
return some(arr) ? arr.join(' ') : '';
}
function join_html (arr) {
var out = [];
if (arr) {
for (var i=0, li=arr.length; i < li; i++) {
out.push(arr[i].html);
}
}
return out.join(' ');
}
function set (props, poi, sfield, dfield) {
var val = first(props[sfield])
poi[dfield || sfield] = val;
}
var mf_processors = {
"h-entry": function (props, poi) {
if (options.nopagelocation && !options.level) { // only at top page
return false;
}
set (props, poi, 'url');
set (props, poi, 'name');
poi.name = options.name || poi.name;
poi.description = join_html(props.summary);
},
"h-item": function (props, poi) {
set (props, poi, 'url');
set (props, poi, 'name');
poi.description = join_html(props.description);
},
"h-card": function (props, poi) {
poi.name || set (props, poi, 'name');
set (props, poi, 'category');
},
"h-geo": function (props, poi) {
set (props, poi, 'name');
set (props, poi, 'longitude');
set (props, poi, 'latitude');
set (props, poi, 'geometry');
},
"h-cite": function (props, poi) {
if ( !(options.recursive > 0))
return false;
var copt = $.extend({}, options);
copt.level++;
if (copt.recursive !== true && ! isNaN(copt.recursive * 1))
copt.recursive--;
set (props, copt, 'url');
if (!copt.url)
return;
set (props, copt, 'name');
if (copt.name)
copt.name = copt.name.split('#', 1)[0].replace(/_/g, ' ');
loadPage(copt);
return false;
},
};
function process_placemark(item_list) {
var poi = {};
for (var i=0, li=item_list.length; i < li; i++) {
var item = item_list[i];
var type = first(item.type);
var props = item.properties;
var processor = mf_processors[type];
if (processor)
if (processor(props, poi) === false)
return;
}
poi.name = poi.name && $.trim(poi.name);
if (!poi.name)
return;
var geometry_encoded = poi.geometry;
if (geometry_encoded) {
var geometry_txt = decodeURIComponent(geometry_encoded.replace(/\+/g,' '));
poi.geometry = kmlFormat.readFeature(geometry_txt).getGeometry();
out(poi);
}
var lon = parseFloat(poi.longitude);
var lat = parseFloat(poi.latitude);
if (!isNaN(lat + lon)) {
poi.geometry = new ol.geom.Point([lon, lat]);
out(poi);
}
}
var mf_subitem_map = {
"h-entry": 'location',
"h-item": 'location',
"h-card": 'geo',
};
function process_item_list (item_list, parents) {
if (!item_list)
return;
for (var i=item_list.length-1; i >= 0; i--) {
var item = item_list[i];
var type = first(item.type);
if (type != 'h-entry' && parents.length == 0 && options.childrenlocations && options.recursive == 0)
continue;
var props = item.properties;
var subitem_id = mf_subitem_map[type];
if (subitem_id) {
process_item_list(item.properties[subitem_id], [item].concat(parents))
} else {
process_placemark([item].concat(parents));
}
if (item.children)
process_item_list(item.children, []);
}
}
var parsed = Microformats.get(options.data);
if (parsed.items && parsed.items.length > 0) {
// console.log('POIs loaded ' + parsed.items.length);
process_item_list(parsed.items, []);
}
//console.log(kml_out);
}
var articlePrefix = wgArticlePath.split('$')[0];
var cgiUriTick = false;
function cgiUri (uri) {
if (uri.indexOf('?') == -1) {
var nameIdx = uri.indexOf(articlePrefix) + articlePrefix.length;
var name = uri.substr(nameIdx);
uri = wikiUri(name);
}
if (cgiUriTick)
uri = uri.replace('//www.', '//');
cgiUriTick = !cgiUriTick;
return uri;
}
function uri2page (uri) {
var shortUri = uri.indexOf('?') == -1
var prefix = shortUri ? articlePrefix : 'title=';
var start = uri.indexOf(prefix) + prefix.length;
var end = shortUri ? -1 : uri.indexOf('?', start);
var page = uri.substring(start, end == -1? uri.length : end);
return page;
}
var loadedPages = {};
function loadPage (options) {
if (!options.level)
options.level = 0;
// var name = options.name = options.name || wgTitle;
// options.url = options.url || wikiUri(wgPageName);
if (options.url) {
var url = cgiUri(options.url);
if (url in loadedPages)
return;
loadedPages[url] = true;
$.get(url + '&redirect=no&action=render', function(data, status) {
if (!data || status != "success")
return;
if (data.indexOf('redirectText') != -1) {
var parsed = $.parseHTML(data.indexOf('<body>') != -1 ? data : '<div>'+data+'</div>');
var redirect = $(parsed).find('.redirectText a').attr('href');
if (redirect) {
options.url = redirect;
loadPage (options);
return;
}
}
options.data = {
'baseUrl': wgServer,
'html': data
};
parsePage(options);
});
} else {
parsePage(options);
}
}
function loadFeatures (options) {
//loadWikiScript('CruisersWiki:Microformat-shiv.min.js', function () {
loadScript('http://cdn.rawgit.com/glennjones/microformat-shiv/v2.0.3/microformat-shiv.js', function () {
if (options.page)
options.url = wikiUri(options.page);
loadPage (options)
});
}
function getArticleLayer (options) {
var iconData = null;
var iconsUrl = 'http://www.cruiserswiki.org/index.php?title=CruisersWiki:Chartlet/icons&action=render';
$.get(iconsUrl, function(data, status) {
iconData = $.parseHTML(data);
addFeature();
});
var defferedFeatures = [];
var addFeature = function (feature) {
if (!iconData) {
defferedFeatures.push(feature);
return;
}
if (defferedFeatures) {
source.addFeatures(defferedFeatures);
defferedFeatures = null;
}
if (feature) {
source.addFeature(feature);
}
};
var loader = function(extent, resolution, projection) {
/**
* @param {ol.Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {ol.proj.Projection} projection Projection.
* @this {ol.source.Vector|ol.VectorTile}
*/
options.projection = projection;
options.addFeature = addFeature;
loadFeatures(options);
};
var iconStyles = {};
function getIconStyle(category) {
var style = iconStyles[category];
if (!style) {
var icon = $(iconData).find('#' + category + ' img');
if (icon.length == 0)
icon = $(iconData).find('#other img');
var styleOptions = {
src: icon.attr('src')
};
/*
var height = parseFloat(icon.attr('height'));
var width = parseFloat(icon.attr('width'));
if (!(isNaN(height) || isNaN(width)))
styleOptions.imgSize = [100,100]; //[width, height];
*/
//styleOptions.imgSize = [40,40];
style = new ol.style.Icon(styleOptions);
iconStyles[category] = style;
}
return style;
}
var textStyles = {};
var textStyleOptions = {
font: 'bold 16px sans-serif',
textAlign: 'center',
offsetY: 18,
fill: new ol.style.Fill({
color: [128, 0, 128, 1]
}),
stroke: new ol.style.Stroke({
color: [255, 255, 224, 1],
//color: [255, 255, 255, 0.5],
width: 4
})
};
function getTextStyle(text) {
textStyleOptions.text = text;
var style = new ol.style.Text(textStyleOptions);
return style;
}
var styleFunction = function (feature, resolution) {
var geom = feature.getGeometry();
if (geom.getType() == 'Point') {
var category = feature.get('category') || 'other';
var styleOptions = {
//zIndex: 2
};
options.icons && (styleOptions.image = getIconStyle(category));
options.captions && (styleOptions.text = getTextStyle(feature.get('name')));
var style = new ol.style.Style(styleOptions);
return style;
} else {
var style = new ol.style.Style({
fill: new ol.style.Fill({
color: [0, 0, 257, 0.05]
}),
stroke: new ol.style.Stroke({
color: [0, 0, 257, 0.5],
width: 2,
lineCap: 'round'
})
});
return style;
}
};
var source = new ol.source.Vector({
loader: loader,
});
var layer = new ol.layer.Vector({
title: 'POI',
visible: true,
style: styleFunction,
source: source,
});
return layer;
};
window.getArticleLayer = getArticleLayer;
})();
//