parent
2e6ba0bb70
commit
b65ea43e34
@ -0,0 +1,20 @@
|
||||
.map {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.add-control {
|
||||
top: 4em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.ol-touch .add-control {
|
||||
top: 5em;
|
||||
}
|
||||
|
||||
.add-control button {
|
||||
width: 8em;
|
||||
font-size: 11pt;
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
const apiUrl = '/horde-members/api/features';
|
||||
const apiKey = 'eyJhbGciOiJIUzUxMiIsImlhdCI6MTU1Mzg5MjYwNSwiZXhwIjoxODY5MjUyNjA1fQ.ImNsaWVudCI.iX2EEEsKbMYpbeU-HB_FcqeepwZn8rkq8XdyfUmr6RJk2-64I744xLdKfrikxskF6_IlJbjBH3jNNcVfWyvswQ';
|
||||
|
||||
var nick = '';
|
||||
|
||||
function store(feature) {
|
||||
var writer = new ol.format.GeoJSON({
|
||||
dataProjection: 'EPSG:4326',
|
||||
featureProjection: 'EPSG:3857'
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: apiUrl,
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: writer.writeFeature(feature),
|
||||
headers: {'X-Members-API-Key': apiKey}
|
||||
});
|
||||
}
|
||||
|
||||
function getColor(nick, alpha) {
|
||||
var r = 0;
|
||||
var g = 0;
|
||||
var b = 0;
|
||||
|
||||
var p1 = nick.length * 351 / 1000 >> 0;
|
||||
var p2 = p1 + nick.length * 206 / 1000 >> 0;
|
||||
|
||||
nick.slice(0, p1).split('').map((c) => {
|
||||
r += c.charCodeAt(0)
|
||||
});
|
||||
nick.slice(p1, p2).split('').map((c) => {
|
||||
g += c.charCodeAt(0)
|
||||
});
|
||||
nick.slice(p2).split('').map((c) => {
|
||||
b += c.charCodeAt(0)
|
||||
});
|
||||
|
||||
r %= 256;
|
||||
g %= 256;
|
||||
b %= 256;
|
||||
|
||||
var k = (299 * r + 587 * g + 114 * b) / 1000;
|
||||
|
||||
while (k > 123) {
|
||||
if (r > 0) r--;
|
||||
if (g > 0) g--;
|
||||
if (b > 0) b--;
|
||||
|
||||
k = (299 * r + 587 * g + 114 * b) / 1000;
|
||||
}
|
||||
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
|
||||
var AddControl = (function (Control) {
|
||||
function AddControl(opt_options) {
|
||||
var options = opt_options || {};
|
||||
|
||||
var button = document.createElement('button');
|
||||
button.innerHTML = 'Add yourself';
|
||||
|
||||
var element = document.createElement('div');
|
||||
element.className = 'add-control ol-unselectable ol-control';
|
||||
element.appendChild(button);
|
||||
|
||||
Control.call(this, {
|
||||
element: element,
|
||||
target: options.target
|
||||
});
|
||||
|
||||
button.addEventListener('click', this.handleAdd.bind(this), false);
|
||||
}
|
||||
|
||||
if (Control)
|
||||
AddControl.__proto__ = Control;
|
||||
|
||||
AddControl.prototype = Object.create(Control && Control.prototype);
|
||||
AddControl.prototype.constructor = AddControl;
|
||||
|
||||
AddControl.prototype.handleAdd = function handleAdd() {
|
||||
nick = prompt('Please enter your nickname', '');
|
||||
};
|
||||
|
||||
return AddControl;
|
||||
}(ol.control.Control));
|
||||
|
||||
var source = new ol.source.Vector({
|
||||
url: apiUrl,
|
||||
wrapX: false,
|
||||
format: new ol.format.GeoJSON({
|
||||
dataProjection: 'EPSG:4326',
|
||||
featureProjection: 'EPSG:3857'
|
||||
})
|
||||
});
|
||||
|
||||
var raster = new ol.layer.Tile({
|
||||
source: new ol.source.OSM()
|
||||
});
|
||||
|
||||
var vector = new ol.layer.Vector({
|
||||
source: source,
|
||||
style: (feature) => new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 6,
|
||||
fill: new ol.style.Fill({
|
||||
color: getColor(feature.get('nick'), 0.8)
|
||||
})
|
||||
}),
|
||||
text: new ol.style.Text({
|
||||
text: feature.get('nick'),
|
||||
font: '12pt sans-serif',
|
||||
textAlign: 'left',
|
||||
offsetY: -20,
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0, 0, 0, 0.8)'
|
||||
}),
|
||||
backgroundFill: new ol.style.Fill({
|
||||
color: 'rgba(255, 255, 255, 0.8)'
|
||||
}),
|
||||
backgroundStroke: new ol.style.Stroke({
|
||||
color: 'rgba(0, 0, 0, 0.8)',
|
||||
width: 1
|
||||
}),
|
||||
padding: [2, 3, 1, 3]
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
target: 'map',
|
||||
layers: [raster, vector],
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
minZoom: 2,
|
||||
zoom: 2
|
||||
}),
|
||||
controls: ol.control.defaults().extend([
|
||||
new AddControl()
|
||||
])
|
||||
});
|
||||
|
||||
var snap = new ol.interaction.Snap({
|
||||
source: source
|
||||
});
|
||||
|
||||
map.addInteraction(snap);
|
||||
|
||||
var modify = new ol.interaction.Modify({
|
||||
source: source,
|
||||
condition: (evt) => {
|
||||
if (!nick)
|
||||
return false;
|
||||
|
||||
var feature = source.getClosestFeatureToCoordinate(evt.coordinate);
|
||||
|
||||
if (!feature)
|
||||
return false;
|
||||
|
||||
return feature.get('current') !== undefined;
|
||||
}
|
||||
});
|
||||
|
||||
modify.on('modifyend', (evt) => {
|
||||
var feature = evt.features.getArray().find((feature) => feature.getRevision() > 1);
|
||||
|
||||
store(feature);
|
||||
});
|
||||
|
||||
map.addInteraction(modify);
|
||||
|
||||
var draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: 'Point',
|
||||
condition: (evt) => {
|
||||
if (!nick)
|
||||
return false;
|
||||
|
||||
var feature = source.forEachFeature((feature) => {
|
||||
if (feature.get('nick') == nick)
|
||||
return feature;
|
||||
});
|
||||
|
||||
if (feature === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (feature.get('current') === undefined)
|
||||
return false;
|
||||
|
||||
var features = [];
|
||||
|
||||
map.forEachFeatureAtPixel(evt.pixel, (feature) => {
|
||||
features.push(feature);
|
||||
});
|
||||
|
||||
return features.length > 1;
|
||||
}
|
||||
});
|
||||
|
||||
draw.on('drawend', (evt) => {
|
||||
var feature = source.forEachFeature((feature) => {
|
||||
if (feature.get('nick') == nick)
|
||||
return feature;
|
||||
});
|
||||
|
||||
if (feature !== undefined)
|
||||
source.removeFeature(feature);
|
||||
|
||||
evt.feature.set('nick', nick);
|
||||
evt.feature.set('current', true);
|
||||
|
||||
store(evt.feature);
|
||||
});
|
||||
|
||||
map.addInteraction(draw);
|
Loading…
Reference in new issue