function get_html_translation_table(table, quote_style) {
// discuss at: http://phpjs.org/functions/get_html_translation_table/
// original by: Philip Peterson
// revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: noname
// bugfixed by: Alex
// bugfixed by: Marco
// bugfixed by: madipta
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: T.Wild
// improved by: KELAN
// improved by: Brett Zamir (http://brett-zamir.me)
// input by: Frank Forte
// input by: Ratheous
// note: It has been decided that we're not going to add global
// note: dependencies to php.js, meaning the constants are not
// note: real constants, but strings instead. Integers are also supported if someone
// note: chooses to create the constants themselves.
// example 1: get_html_translation_table('HTML_SPECIALCHARS');
// returns 1: {'"': '"', '&': '&', '<': '<', '>': '>'}
var entities = {},
hash_map = {},
decimal;
var constMappingTable = {},
constMappingQuoteStyle = {};
var useTable = {},
useQuoteStyle = {};
// Translate arguments
constMappingTable[0] = "HTML_SPECIALCHARS";
constMappingTable[1] = "HTML_ENTITIES";
constMappingQuoteStyle[0] = "ENT_NOQUOTES";
constMappingQuoteStyle[2] = "ENT_COMPAT";
constMappingQuoteStyle[3] = "ENT_QUOTES";
useTable = !isNaN(table)
? constMappingTable[table]
: table
? table.toUpperCase()
: "HTML_SPECIALCHARS";
useQuoteStyle = !isNaN(quote_style)
? constMappingQuoteStyle[quote_style]
: quote_style
? quote_style.toUpperCase()
: "ENT_COMPAT";
if (useTable !== "HTML_SPECIALCHARS" && useTable !== "HTML_ENTITIES") {
throw new Error("Table: " + useTable + " not supported");
// return false;
}
entities["38"] = "&";
if (useTable === "HTML_ENTITIES") {
entities["160"] = " ";
entities["161"] = "¡";
entities["162"] = "¢";
entities["163"] = "£";
entities["164"] = "¤";
entities["165"] = "¥";
entities["166"] = "¦";
entities["167"] = "§";
entities["168"] = "¨";
entities["169"] = "©";
entities["170"] = "ª";
entities["171"] = "«";
entities["172"] = "¬";
entities["173"] = "­";
entities["174"] = "®";
entities["175"] = "¯";
entities["176"] = "°";
entities["177"] = "±";
entities["178"] = "²";
entities["179"] = "³";
entities["180"] = "´";
entities["181"] = "µ";
entities["182"] = "¶";
entities["183"] = "·";
entities["184"] = "¸";
entities["185"] = "¹";
entities["186"] = "º";
entities["187"] = "»";
entities["188"] = "¼";
entities["189"] = "½";
entities["190"] = "¾";
entities["191"] = "¿";
entities["192"] = "À";
entities["193"] = "Á";
entities["194"] = "Â";
entities["195"] = "Ã";
entities["196"] = "Ä";
entities["197"] = "Å";
entities["198"] = "Æ";
entities["199"] = "Ç";
entities["200"] = "È";
entities["201"] = "É";
entities["202"] = "Ê";
entities["203"] = "Ë";
entities["204"] = "Ì";
entities["205"] = "Í";
entities["206"] = "Î";
entities["207"] = "Ï";
entities["208"] = "Ð";
entities["209"] = "Ñ";
entities["210"] = "Ò";
entities["211"] = "Ó";
entities["212"] = "Ô";
entities["213"] = "Õ";
entities["214"] = "Ö";
entities["215"] = "×";
entities["216"] = "Ø";
entities["217"] = "Ù";
entities["218"] = "Ú";
entities["219"] = "Û";
entities["220"] = "Ü";
entities["221"] = "Ý";
entities["222"] = "Þ";
entities["223"] = "ß";
entities["224"] = "à";
entities["225"] = "á";
entities["226"] = "â";
entities["227"] = "ã";
entities["228"] = "ä";
entities["229"] = "å";
entities["230"] = "æ";
entities["231"] = "ç";
entities["232"] = "è";
entities["233"] = "é";
entities["234"] = "ê";
entities["235"] = "ë";
entities["236"] = "ì";
entities["237"] = "í";
entities["238"] = "î";
entities["239"] = "ï";
entities["240"] = "ð";
entities["241"] = "ñ";
entities["242"] = "ò";
entities["243"] = "ó";
entities["244"] = "ô";
entities["245"] = "õ";
entities["246"] = "ö";
entities["247"] = "÷";
entities["248"] = "ø";
entities["249"] = "ù";
entities["250"] = "ú";
entities["251"] = "û";
entities["252"] = "ü";
entities["253"] = "ý";
entities["254"] = "þ";
entities["255"] = "ÿ";
}
if (useQuoteStyle !== "ENT_NOQUOTES") {
entities["34"] = """;
}
if (useQuoteStyle === "ENT_QUOTES") {
entities["39"] = "'";
}
entities["60"] = "<";
entities["62"] = ">";
// ascii decimals to real symbols
for (decimal in entities) {
if (entities.hasOwnProperty(decimal)) {
hash_map[String.fromCharCode(decimal)] = entities[decimal];
}
}
return hash_map;
}
function html_entity_decode(string, quote_style) {
// discuss at: http://phpjs.org/functions/html_entity_decode/
// original by: john (http://www.jd-tech.net)
// input by: ger
// input by: Ratheous
// input by: Nick Kolosov (http://sammy.ru)
// improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// improved by: marc andreu
// revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// bugfixed by: Onno Marsman
// bugfixed by: Brett Zamir (http://brett-zamir.me)
// bugfixed by: Fox
// depends on: get_html_translation_table
// example 1: html_entity_decode('Kevin & van Zonneveld');
// returns 1: 'Kevin & van Zonneveld'
// example 2: html_entity_decode('&lt;');
// returns 2: '<'
var hash_map = {},
symbol = "",
tmp_str = "",
entity = "";
tmp_str = string.toString();
if (
false ===
(hash_map = this.get_html_translation_table("HTML_ENTITIES", quote_style))
) {
return false;
}
// fix & problem
// http://phpjs.org/functions/get_html_translation_table:416#comment_97660
delete hash_map["&"];
hash_map["&"] = "&";
for (symbol in hash_map) {
entity = hash_map[symbol];
tmp_str = tmp_str.split(entity).join(symbol);
}
tmp_str = tmp_str.split("'").join("'");
return tmp_str;
}
/// <reference path="../typings/jquery/jquery.d.ts"/>
/* global L */
//The javascript accompanying jamesgardiner.gihub.io/blog/police_data_api_in_leaflet
//initialise global variables
var forcesJSON;
var forces;
var neighbourhoods;
var areaLayer;
var i;
// create the map object and set the cooridnates of the initial view:
var map = L.map("map").setView([51.4833, -3.1833], 10);
// create the tile layer with correct attribution:
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
maxZoom: 18
}).addTo(map);
//extend the L.Control class to create a custom drop down box populated with a list
//of police forces in England & Wales.
var ForceControl = L.Control.extend({
initialize: function (name, options) {
L.Util.setOptions(this, options);
},
//function to be called when the control is added to the map
onAdd: function (map) {
// create the control container with a particular class name
var container = L.DomUtil.create("div", "dropdown-control");
//create a list of available police force names and ids
//using the data.police.uk api Forces method inside the
//'force' global variable.
forces = [];
$.getJSON("https://data.police.uk/api/forces", function (data) {
var htmlString =
"<label>Police force: <select id=forcesList " +
'onchange="updateNeighbourhoods()"><option>' +
"Select a Force</option>";
$.each(data, function (i, item) {
forces[i] = item;
htmlString = htmlString + "<option>" + forces[i].name + "</option>";
});
htmlString += "</select>";
//update the dropdown list innerhtml with the list of forces
container.innerHTML = htmlString;
//allow a user to select a single option
container.firstChild.onmousedown = container.firstChild.ondblclick =
L.DomEvent.stopPropagation;
});
return container;
}
});
//extend the L.Control class to create a custom drop down box
// initially with simple placeholder text
var NeighbourhoodControl = L.Control.extend({
initialize: function (name, options, placeholder) {
L.Util.setOptions(this, options);
},
//once added to the map div, carry out the following
onAdd: function (map) {
//create the control container with a particular class name
var container = L.DomUtil.create("div", "dropdown-control");
//add the following to the innerHTML
var htmlString =
'<label>Neighbourhood:<select id="neighbourhoodsList" ' +
'onchange="neighbourhoodChanged()" onclick="neighbourhoodChanged()">' +
"<option>Select a neighbourhood</option></select>";
container.innerHTML = htmlString;
//allow a user to select a single option
container.firstChild.onmousedown = container.firstChild.ondblclick =
L.DomEvent.stopPropagation;
return container;
}
});
map.addControl(new ForceControl("forcesList", { position: "topright" }));
map.addControl(
new NeighbourhoodControl("neighbourhoodList", { position: "topright" })
);
//update the current list of neighbourhoods using the selected force id
var updateNeighbourhoods = function (name) {
//get the force name
var force = $("#forcesList").val();
//empty the neighbourhoods array
neighbourhoods = [];
//find the force id for the api call
for (i in forces) {
if (forces[i].name === force) {
var id = forces[i].id;
}
}
//if the id is matched successfully then get a list of neighbourhoods in
//that force area.
if (id) {
var url = "https://data.police.uk/api/" + id + "/neighbourhoods";
$.getJSON(url, function (data) {
var htmlString = '<select id="neighbourhoodsList">';
$.each(data, function (i, item) {
neighbourhoods[i] = item;
htmlString =
htmlString + "<option>" + neighbourhoods[i].name + "</option>";
});
htmlString = htmlString + "</select>";
//change the innerHTML
$("#neighbourhoodsList").html(htmlString);
//reorder the options
$("#neighbourhoodsList").html(
$("#neighbourhoodsList option").sort(function (a, b) {
return a.text == b.text ? 0 : a.text < b.text ? -1 : 1;
})
);
//Prepend a placeholder so that onchange is fired when user selects
$("#neighbourhoodsList").prepend(
$("<option>Select a neighbourhood</option>")
);
});
} else {
$("#neighbourhoodsList").html(
'<select id="neighbourhoodsList"><option>Select a police force</option></select>'
);
}
};
//function called when the selected neighbourhood is changed
var neighbourhoodChanged = function () {
//get the selected 'hood name
var hood = $("#neighbourhoodsList").val();
//compare the name of the 'hood to get the id
for (i in neighbourhoods) {
if (
html_entity_decode(neighbourhoods[i].name) === html_entity_decode(hood)
) {
var id = [];
id[0] = neighbourhoods[i].id;
}
}
//compare the name of the force to get the id
var force = $("#forcesList").val();
for (i in forces) {
if (forces[i].name === force) {
id[1] = forces[i].id;
}
}
//if we match both the force and 'hood then carry on, else break
if (id[0] && id[1]) {
var latlng = [];
var url = "https://data.police.uk/api/" + id[1] + "/" + id[0] + "/boundary";
$.getJSON(url, function (data) {
//create an array of boundary lat lon pairs
$.each(data, function (i, item) {
latlng.push(new L.LatLng(data[i].latitude, data[i].longitude));
});
//if a layer is already present, remove it
if (areaLayer) {
map.removeLayer(areaLayer);
}
//create a new polygon object using the latlng array
areaLayer = new L.Polygon(latlng, {
clickable: true,
weight: 3,
opacity: 0.4,
fillOpacity: 0.1
});
//redraw the map to the bounds of the new polygon
map.fitBounds(areaLayer.getBounds());
//add the polygon to the map
areaLayer.addTo(map);
});
}
};