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) {
poi.geometry.transform('EPSG:4326', options.projection);
var feature = new ol.Feature(poi);
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,' '));
var kml_features = kmlFormat.readFeatures(geometry_txt);
if (kml_features.length > 0) {
poi.geometry = kml_features[0].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];
function cgiUri (uri) {
if (uri.indexOf('?') != -1)
return uri;
var nameIdx = uri.indexOf(articlePrefix) + articlePrefix.length;
var name = uri.substr(nameIdx);
return wikiUri(name);
}
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 () {
loadScript('http://cdn.rawgit.com/glennjones/microformat-shiv/v2.0.3/microformat-shiv.min.js', function () {
if (options.page)
options.url = wikiUri(options.page);
loadPage (options)
});
}
function parseStyles (html) {
var categoryStyles = {};
var dom = $.parseHTML(html);
$(dom).find('.chartlet-style').each( function (idx) {
var txt = this.text();
try {
var def = JSON.parse(txt);
} catch (e) {
console.log(e);
}
var styles = {};
$.each( ['Icon', 'Stroke', 'Fill', 'Text'], function (x, key) {
var val = def[key];
if (!val)
return;
if (key == 'Text') {
val['stroke'] = new ol.style.Stroke(def['TextStroke']);
val['fill'] = new ol.style.Fill(def['TextFill']);
}
styles[key] = new ol.style[key](def);
});
categoryStyles[this.id] = def;
})
return categoryStyles;
}
function getArticleLayer (options) {
var styles = null;
var iconsUrl = 'http://www.cruiserswiki.org/index.php?title=CruisersWiki:Chartlet/config&action=render';
$.get(iconsUrl, function(data, status) {
styles = parseStyles(data);
addFeature();
});
var defferedFeatures = [];
var addFeature = function (feature) {
if (!styles) {
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);
};
function getStyle(category, kind) {
var catStyles = styles[category];
if (!catStyles) {
catStyles = styles[category] = {};
$.each(styles['default'], function(key, val) {
catStyles[key] = styles['default'][key].clone();
});
}
var style = catStyles[kind];
if (!style) {
style = catStyles[kind] = styles['default'][kind].clone();
}
return style;
}
function getTextStyle(category, text) {
var style = getStyle(category, 'Text').clone();
style.setText(text);
return style;
}
var styleFunction = function (feature, resolution) {
var category = feature.get('category') || 'other';
var geom = feature.getGeometry();
var style;
if (geom.getType() == 'Point') {
var styleOptions = {
//zIndex: 2
};
options.icons && (styleOptions.image = getStyle(category, 'Icon'));
options.captions && (styleOptions.text = getTextStyle(category, feature.get('name')));
style = new ol.style.Style(styleOptions);
} else {
style = new ol.style.Style({
fill: getStyle(category, 'Fill'),
stroke: getStyle(category, 'Stroke'),
});
}
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;
})();
//