From CruisersWiki
//
/*
features.js
Copyright (c) 2016 Vadim Shlyakhov
Licensed MIT
*/
(function () {
var articlePrefix = wgArticlePath.split('$')[0];
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) {
set (props, poi, 'url');
//set (props, poi, 'name');
poi.name = options.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;
var copt = $.extend({}, options);
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);
},
};
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];
processor && processor(props, poi);
}
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);
}
function cgiUri (uri) {
if (uri.indexOf('?') != -1)
return uri;
var nameIdx = uri.indexOf(articlePrefix) + articlePrefix.length;
var name = uri.substr(nameIdx);
return wikiUri(name);
}
var loadedPages = {};
function loadPage (options) {
var name = options.name = options.name || wgPageName;
options.url = options.url || wikiUri(name);
var url = cgiUri(options.url);
if (url in loadedPages)
return;
loadedPages[url] = true;
if (name != wgPageName) {
$.get(url + '&redirect=no', function(data, status) {
if (!data || status != "success")
return;
if (data.indexOf('redirectText') != -1) {
var parsed = $.parseHTML(data);
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 () {
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.1]
}),
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;
})();
//