Jon Atkins 5fc9bf7f8e draw tools:
- broken localStorage data won't prevent plugin from loading
- import: validate data better on import - json parse before erasing current items, try/catch around whole import process, and existing save method writes back to storage
2014-01-29 05:57:32 +00:00

395 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @id iitc-plugin-draw-tools@breunigs
// @name IITC plugin: draw tools
// @category Layer
// @version 0.6.0.@@DATETIMEVERSION@@
// @namespace https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL @@UPDATEURL@@
// @downloadURL @@DOWNLOADURL@@
// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow drawing things onto the current map so you may plan your next move.
// @include https://www.ingress.com/intel*
// @include http://www.ingress.com/intel*
// @match https://www.ingress.com/intel*
// @match http://www.ingress.com/intel*
// @grant none
// ==/UserScript==
@@PLUGINSTART@@
// PLUGIN START ////////////////////////////////////////////////////////
// use own namespace for plugin
window.plugin.drawTools = function() {};
window.plugin.drawTools.loadExternals = function() {
try { console.log('Loading leaflet.draw JS now'); } catch(e) {}
@@INCLUDERAW:external/leaflet.draw.js@@
@@INCLUDERAW:external/spectrum/spectrum.js@@
try { console.log('done loading leaflet.draw JS'); } catch(e) {}
window.plugin.drawTools.boot();
$('head').append('<style>@@INCLUDESTRING:external/leaflet.draw.css@@</style>');
$('head').append('<style>@@INCLUDESTRING:external/spectrum/spectrum.css@@</style>');
}
window.plugin.drawTools.currentColor = '#a24ac3';
window.plugin.drawTools.setOptions = function() {
window.plugin.drawTools.lineOptions = {
stroke: true,
color: window.plugin.drawTools.currentColor,
weight: 4,
opacity: 0.5,
fill: false,
clickable: true
};
window.plugin.drawTools.polygonOptions = L.extend({}, window.plugin.drawTools.lineOptions, {
fill: true,
fillColor: null, // to use the same as 'color' for fill
fillOpacity: 0.2
});
window.plugin.drawTools.editOptions = L.extend({}, window.plugin.drawTools.polygonOptions, {
dashArray: [10,10]
});
delete window.plugin.drawTools.editOptions.color;
window.plugin.drawTools.markerOptions = {
icon: new L.Icon.Default(),
zIndexOffset: 2000
};
}
window.plugin.drawTools.setDrawColor = function(color) {
window.plugin.drawTools.currentColor = color;
window.plugin.drawTools.drawControl.setDrawingOptions({
'polygon': { 'shapeOptions': { color: color } },
'polyline': { 'shapeOptions': { color: color } },
'circle': { 'shapeOptions': { color: color } },
});
}
// renders the draw control buttons in the top left corner
window.plugin.drawTools.addDrawControl = function() {
var drawControl = new L.Control.Draw({
draw: {
rectangle: false,
polygon: {
title: 'Add a polygon\n\n'
+ 'Click on the button, then click on the map to\n'
+ 'define the start of the polygon. Continue clicking\n'
+ 'to draw the line you want. Click the first or last\n'
+ 'point of the line (a small white rectangle) to\n'
+ 'finish. Double clicking also works.',
shapeOptions: window.plugin.drawTools.polygonOptions,
snapPoint: window.plugin.drawTools.getSnapLatLng,
},
polyline: {
title: 'Add a (poly) line.\n\n'
+ 'Click on the button, then click on the map to\n'
+ 'define the start of the line. Continue clicking\n'
+ 'to draw the line you want. Click the <b>last</b>\n'
+ 'point of the line (a small white rectangle) to\n'
+ 'finish. Double clicking also works.',
shapeOptions: window.plugin.drawTools.lineOptions,
snapPoint: window.plugin.drawTools.getSnapLatLng,
},
circle: {
title: 'Add a circle.\n\n'
+ 'Click on the button, then click-AND-HOLD on the\n'
+ 'map where the circles center should be. Move\n'
+ 'the mouse to control the radius. Release the mouse\n'
+ 'to finish.',
shapeOptions: window.plugin.drawTools.polygonOptions,
snapPoint: window.plugin.drawTools.getSnapLatLng,
},
marker: {
title: 'Add a marker.\n\n'
+ 'Click on the button, then click on the map where\n'
+ 'you want the marker to appear.',
shapeOptions: window.plugin.drawTools.markerOptions,
snapPoint: window.plugin.drawTools.getSnapLatLng,
repeatMode: true,
},
},
edit: {
featureGroup: window.plugin.drawTools.drawnItems,
edit: {
title: 'Edit drawn items',
selectedPathOptions: window.plugin.drawTools.editOptions,
},
remove: {
title: 'Delete drawn items'
},
},
});
window.plugin.drawTools.drawControl = drawControl;
map.addControl(drawControl);
// plugin.drawTools.addCustomButtons();
}
// given a point it tries to find the most suitable portal to
// snap to. It takes the CircleMarkers radius and weight into account.
// Will return null if nothing to snap to or a LatLng instance.
window.plugin.drawTools.getSnapLatLng = function(unsnappedLatLng) {
var containerPoint = map.latLngToContainerPoint(unsnappedLatLng);
var candidates = [];
$.each(window.portals, function(guid, portal) {
var ll = portal.getLatLng();
var pp = map.latLngToContainerPoint(ll);
var size = portal.options.weight + portal.options.radius;
var dist = pp.distanceTo(containerPoint);
if(dist > size) return true;
candidates.push([dist, ll]);
});
if(candidates.length === 0) return unsnappedLatLng;
candidates = candidates.sort(function(a, b) { return a[0]-b[0]; });
return candidates[0][1];
}
window.plugin.drawTools.save = function() {
var data = [];
window.plugin.drawTools.drawnItems.eachLayer( function(layer) {
console.log(layer);
var item = {};
if (layer instanceof L.GeodesicCircle || layer instanceof L.Circle) {
item.type = 'circle';
item.latLng = layer.getLatLng();
item.radius = layer.getRadius();
item.color = layer.options.color;
} else if (layer instanceof L.GeodesicPolygon || layer instanceof L.Polygon) {
item.type = 'polygon';
item.latLngs = layer.getLatLngs();
item.color = layer.options.color;
} else if (layer instanceof L.GeodesicPolyline || layer instanceof L.Polyline) {
item.type = 'polyline';
item.latLngs = layer.getLatLngs();
item.color = layer.options.color;
} else if (layer instanceof L.Marker) {
item.type = 'marker';
item.latLng = layer.getLatLng();
} else {
console.warn('Unknown layer type when saving draw tools layer');
return; //.eachLayer 'continue'
}
data.push(item);
});
localStorage['plugin-draw-tools-layer'] = JSON.stringify(data);
console.log('draw-tools: saved to localStorage');
}
window.plugin.drawTools.load = function() {
try {
var dataStr = localStorage['plugin-draw-tools-layer'];
if (dataStr === undefined) return;
var data = JSON.parse(dataStr);
window.plugin.drawTools.import(data);
} catch(e) {
console.warn('draw-tools: failed to load data from localStorage: '+e);
}
}
window.plugin.drawTools.import = function(data) {
$.each(data, function(index,item) {
var layer = null;
var extraOpt = {};
if (item.color) extraOpt.color = item.color;
switch(item.type) {
case 'polyline':
layer = L.geodesicPolyline(item.latLngs, L.extend({},window.plugin.drawTools.lineOptions,extraOpt));
break;
case 'polygon':
layer = L.geodesicPolygon(item.latLngs, L.extend({},window.plugin.drawTools.polygonOptions,extraOpt));
break;
case 'circle':
layer = L.geodesicCircle(item.latLng, item.radius, L.extend({},window.plugin.drawTools.polygonOptions,extraOpt));
break;
case 'marker':
layer = L.marker(item.latLng, window.plugin.drawTools.markerOptions);
break;
default:
console.warn('unknown layer type "'+item.type+'" when loading draw tools layer');
break;
}
if (layer) {
window.plugin.drawTools.drawnItems.addLayer(layer);
}
});
}
//Draw Tools Options
// Manual import, export and reset data
window.plugin.drawTools.manualOpt = function() {
var html = '<div class="drawtoolsStyles">'
+ '<input type="color" name="drawColor" id="drawtools_color"></input>'
//TODO: add line style choosers: thickness, maybe dash styles?
+ '</div>'
+ '<div class="drawtoolsSetbox">'
+ '<a onclick="window.plugin.drawTools.optCopy();">Copy/Export Drawn Items</a>'
+ '<a onclick="window.plugin.drawTools.optPaste();return false;">Paste/Import Drawn Items</a>'
+ '<a onclick="window.plugin.drawTools.optReset();return false;">Reset Drawn Items</a>'
+ '</div>';
dialog({
html: html,
dialogClass: 'ui-dialog-drawtoolsSet',
title: 'Draw Tools Options'
});
// need to initialise the 'spectrum' colour picker
$('#drawtools_color').spectrum({
flat: false,
showInput: false,
showButtons: false,
showPalette: true,
showSelectionPalette: false,
palette: [ ['#a24ac3','#514ac3','#4aa8c3','#51c34a'],
['#c1c34a','#c38a4a','#c34a4a','#c34a6f'],
['#000000','#666666','#bbbbbb','#ffffff']
],
change: function(color) { window.plugin.drawTools.setDrawColor(color.toHexString()); },
// move: function(color) { window.plugin.drawTools.setDrawColor(color.toHexString()); },
color: window.plugin.drawTools.currentColor,
});
}
window.plugin.drawTools.optAlert = function(message) {
$('.ui-dialog-drawtoolsSet .ui-dialog-buttonset').prepend('<p class="drawtools-alert" style="float:left;margin-top:4px;">'+message+'</p>');
$('.drawtools-alert').delay(2500).fadeOut();
}
window.plugin.drawTools.optCopy = function() {
dialog({
html: '<p><a onclick="$(\'.ui-dialog-drawtoolsSet-copy textarea\').select();">Select all</a> and press CTRL+C to copy it.</p><textarea readonly onclick="$(\'.ui-dialog-drawtoolsSet-copy textarea\').select();">'+localStorage['plugin-draw-tools-layer']+'</textarea>',
width: 600,
dialogClass: 'ui-dialog-drawtoolsSet-copy',
title: 'Draw Tools Export'
});
}
window.plugin.drawTools.optPaste = function() {
var promptAction = prompt('Press CTRL+V to paste it.', '');
if(promptAction !== null && promptAction !== '') {
try {
var data = JSON.parse(promptAction);
window.plugin.drawTools.drawnItems.clearLayers();
window.plugin.drawTools.import(data);
console.log('DRAWTOOLS: reset and imported drawn tiems');
window.plugin.drawTools.optAlert('Import Successful.');
// to write back the data to localStorage
window.plugin.drawTools.save();
} catch(e) {
console.warn('DRAWTOOLS: failed to import data: '+e);
window.plugin.drawTools.optAlert('<span style="color: #f88">Import failed</span>');
}
}
}
window.plugin.drawTools.optReset = function() {
var promptAction = confirm('All drawn items will be deleted. Are you sure?', '');
if(promptAction) {
delete localStorage['plugin-draw-tools-layer'];
window.plugin.drawTools.drawnItems.clearLayers();
window.plugin.drawTools.load();
console.log('DRAWTOOLS: reset all drawn items');
window.plugin.drawTools.optAlert('Reset Successful. ');
}
}
window.plugin.drawTools.boot = function() {
window.plugin.drawTools.setOptions();
//create a leaflet FeatureGroup to hold drawn items
window.plugin.drawTools.drawnItems = new L.FeatureGroup();
//load any previously saved items
plugin.drawTools.load();
//add the draw control - this references the above FeatureGroup for editing purposes
plugin.drawTools.addDrawControl();
//start off hidden. if the layer is enabled, the below addLayerGroup will add it, triggering a 'show'
$('.leaflet-draw-section').hide();
//hide the draw tools when the 'drawn items' layer is off, show it when on
map.on('layeradd', function(obj) {
if(obj.layer === window.plugin.drawTools.drawnItems) {
$('.leaflet-draw-section').show();
}
});
map.on('layerremove', function(obj) {
if(obj.layer === window.plugin.drawTools.drawnItems) {
$('.leaflet-draw-section').hide();
}
});
//add the layer
window.addLayerGroup('Drawn Items', window.plugin.drawTools.drawnItems, true);
//place created items into the specific layer
map.on('draw:created', function(e) {
var type=e.layerType;
var layer=e.layer;
window.plugin.drawTools.drawnItems.addLayer(layer);
window.plugin.drawTools.save();
});
map.on('draw:deleted', function(e) {
window.plugin.drawTools.save();
});
map.on('draw:edited', function(e) {
window.plugin.drawTools.save();
});
//add options menu
$('#toolbox').append('<a onclick="window.plugin.drawTools.manualOpt();return false;">DrawTools Opt</a>');
$('head').append('<style>' +
'.drawtoolsSetbox > a { display:block; color:#ffce00; border:1px solid #ffce00; padding:3px 0; margin:10px auto; width:80%; text-align:center; background:rgba(8,48,78,.9); }'+
'.ui-dialog-drawtoolsSet-copy textarea { width:96%; height:250px; resize:vertical; }'+
'</style>');
}
var setup = window.plugin.drawTools.loadExternals;
// PLUGIN END //////////////////////////////////////////////////////////
@@PLUGINEND@@