From 75dea672f32b56bbb9d3dc896b326384695e0e51 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 05:56:29 -0800 Subject: [PATCH 1/9] Inital stab at mu counts for fields Still needs work on when not to display, maybe based on field area and zoom level? --- code/map_data.js | 40 ++++++++++++++++++++++++++++++++-------- style.css | 9 +++++++++ 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 363240c4..2366b533 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -179,10 +179,13 @@ window.cleanUp = function() { cnt[1]++; linksLayer.removeLayer(link); }); - fieldsLayer.eachLayer(function(field) { - if(b.intersects(field.getBounds())) return; - cnt[2]++; - fieldsLayer.removeLayer(field); + fieldsLayer.eachLayer(function(fieldgroup) { + fieldgroup.eachLayer(function(item) { + if(!item.options.guid) return true; + if(b.intersects(item.getBounds())) return; + cnt[2]++; + fieldsLayer.removeLayer(fieldgroup); + }); }); console.log('removed out-of-bounds: '+cnt[0]+' portals, '+cnt[1]+' links, '+cnt[2]+' fields'); } @@ -537,8 +540,6 @@ window.renderField = function(ent) { stroke: false, clickable: false, smoothFactor: 0, // hiding small fields will be handled below - vertices: reg, - lastUpdate: ent[1], guid: ent[0]}); // determine which fields are too small to be rendered and don’t @@ -553,14 +554,37 @@ window.renderField = function(ent) { if(!getPaddedBounds().intersects(poly.getBounds())) return; + var centroid = [ + (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, + (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 + ]; + + var fieldMu = L.marker(centroid, { + icon: L.divIcon({ + className: 'fieldmu', + iconSize: [100,12], + html: 'MU: ' + ent[2].entityScore.entityScore}), + clickable: false + }); + + // put both in one group, so they can be handled by the same logic. + var f = L.layerGroup([poly, fieldMu], { + vertices: reg, + lastUpdate: ent[1], + guid: ent[0]}); + + // However, LayerGroups (and FeatureGroups) don’t fire add/remove + // events, thus this listener will be attached to the field. It + // doesn’t matter to which element these are bound since Leaflet + // will add/remove all elements of the LayerGroup at once. poly.on('remove', function() { delete window.fields[this.options.guid]; }); poly.on('add', function() { // enable for debugging if(window.fields[this.options.guid]) console.warn('duplicate field detected'); - window.fields[this.options.guid] = this; + window.fields[this.options.guid] = f; this.bringToBack(); }); - poly.addTo(fieldsLayer); + f.addTo(fieldsLayer); } diff --git a/style.css b/style.css index 3ebf08bc..39d6cc49 100644 --- a/style.css +++ b/style.css @@ -93,6 +93,15 @@ a:hover { width: 0; } +/* field mu count */ + +.fieldmu { + color: #FFCE00; + font-size:13px; + font-family: "coda",arial,helvetica,sans-serif; /*override leaflet-container */ + text-align: center; +} + /* chat ***************************************************************/ From 1e21bbb94d0d9c5e4311634045da79751604aa5b Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 06:29:35 -0800 Subject: [PATCH 2/9] Add thousands separator and bug fix --- code/map_data.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2366b533..2731ff1a 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -563,15 +563,17 @@ window.renderField = function(ent) { icon: L.divIcon({ className: 'fieldmu', iconSize: [100,12], - html: 'MU: ' + ent[2].entityScore.entityScore}), + html: 'MU: ' + digits(ent[2].entityScore.entityScore)}), clickable: false }); // put both in one group, so they can be handled by the same logic. - var f = L.layerGroup([poly, fieldMu], { + var f = L.layerGroup([poly, fieldMu]); + f.options = { vertices: reg, lastUpdate: ent[1], - guid: ent[0]}); + guid: ent[0] + }; // However, LayerGroups (and FeatureGroups) don’t fire add/remove // events, thus this listener will be attached to the field. It From 0ba8631b82e30bff164f4f4af6bd3719a7f53dc1 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:25:03 -0800 Subject: [PATCH 3/9] MU counts for fields with limiting for small fields Only at higher zoom levels will counts for small fields show. --- code/map_data.js | 40 +++++++++++++++++++++++++++++----------- code/utils_misc.js | 5 +++++ main.js | 2 ++ style.css | 2 +- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2731ff1a..529f9c70 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -522,17 +522,30 @@ window.renderField = function(ent) { if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return window.removeByGuid(ent[0]); - // assume that fields never change. If they do, they will have a - // different ID. - if(findEntityInLeaflet(fieldsLayer, fields, ent[0])) return; - - var team = getTeam(ent[2]); var reg = ent[2].capturedRegion; var latlngs = [ - [reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6], - [reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6], - [reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6] + new L.LatLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), + new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), + new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) + + // Do nothing if zoom did not change. We need to recheck the field if the + // zoom level is different then when the field was rendered as it could + // now be appropriate or not to show an MU count + var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); + if(old) { + if(map.getZoom() == old.options.creationZoom) return; + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; + }); + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + removeByGuid(ent[0]); + } + + var team = getTeam(ent[2]); var poly = L.polygon(latlngs, { fillColor: COLORS[team], @@ -562,16 +575,21 @@ window.renderField = function(ent) { var fieldMu = L.marker(centroid, { icon: L.divIcon({ className: 'fieldmu', - iconSize: [100,12], - html: 'MU: ' + digits(ent[2].entityScore.entityScore)}), + iconSize: [70,12], + html: digits(ent[2].entityScore.entityScore)}), clickable: false }); // put both in one group, so they can be handled by the same logic. - var f = L.layerGroup([poly, fieldMu]); + if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO) { + var f = L.layerGroup([poly, fieldMu]); + } else { + var f = L.layerGroup([poly]); + } f.options = { vertices: reg, lastUpdate: ent[1], + creationZoom: map.getZoom(), guid: ent[0] }; diff --git a/code/utils_misc.js b/code/utils_misc.js index 1e5e0a87..270ce855 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -296,3 +296,8 @@ window.convertTextToTableMagic = function(text) { table += ''; return table; } + +// Given 3 sets of points in an array[3]{lat, lng} returns the area of the triangle +window.calcTriArea = function(p) { + return Math.abs((p[0].lat*(p[1].lng-p[2].lng)+p[1].lat*(p[2].lng-p[0].lng)+p[2].lat*(p[0].lng-p[1].lng))/2); +} diff --git a/main.js b/main.js index 7553fd48..04a62374 100644 --- a/main.js +++ b/main.js @@ -149,6 +149,8 @@ window.MAX_DRAWN_LINKS = 400; window.MAX_DRAWN_FIELDS = 200; // Minimum zoom level resonator will display window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17; +// Minimum area to zoom ratio that field MU's will display +window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001; window.COLOR_SELECTED_PORTAL = '#f00'; window.COLORS = ['#FFCE00', '#0088FF', '#03DC03']; // none, res, enl diff --git a/style.css b/style.css index 39d6cc49..7763bb22 100644 --- a/style.css +++ b/style.css @@ -94,12 +94,12 @@ a:hover { } /* field mu count */ - .fieldmu { color: #FFCE00; font-size:13px; font-family: "coda",arial,helvetica,sans-serif; /*override leaflet-container */ text-align: center; + text-shadow: 0 0 0.2em black, 0 0 0.2em black, 0 0 0.2em black; } From d4903c6ce7b12b04e574dc6ca1b471d9fc15fbf6 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:38:13 -0800 Subject: [PATCH 4/9] Code breaking bug fix --- code/map_data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/map_data.js b/code/map_data.js index 157ab1d6..2f055253 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -609,7 +609,7 @@ window.renderField = function(ent) { lastUpdate: ent[1], creationZoom: map.getZoom(), guid: ent[0], - data: ent[2]}); + data: ent[2] }; // However, LayerGroups (and FeatureGroups) don’t fire add/remove From 7c019e1eb8d35b1fe3b67b6529a03b9418c37b2d Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 21:51:12 -0800 Subject: [PATCH 5/9] Fix tabs and add comment about crazy equation --- code/map_data.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 2f055253..43f59b87 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -546,6 +546,8 @@ window.renderField = function(ent) { new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; + + // Curve fit equation to normalize zoom window area var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) // Do nothing if zoom did not change. We need to recheck the field if the @@ -554,12 +556,12 @@ window.renderField = function(ent) { var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); if(old) { if(map.getZoom() == old.options.creationZoom) return; - var layerCount = 0; - old.eachLayer(function(item) { - layerCount++; - }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; + }); + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; removeByGuid(ent[0]); } From 9889e0988f905769bfe9310dd618061b6f06204b Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 2 Mar 2013 22:27:45 -0800 Subject: [PATCH 6/9] Fix to use identity operators --- code/map_data.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 43f59b87..b9c71724 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -555,13 +555,13 @@ window.renderField = function(ent) { // now be appropriate or not to show an MU count var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); if(old) { - if(map.getZoom() == old.options.creationZoom) return; + if(map.getZoom() === old.options.creationZoom) return; var layerCount = 0; old.eachLayer(function(item) { layerCount++; }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount == 1) return; + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 2) return; + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 1) return; removeByGuid(ent[0]); } From e3b9a2b1ec799ce8622167168b79e707b9cefc01 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 01:08:46 -0800 Subject: [PATCH 7/9] Fix up nits --- code/map_data.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index b9c71724..dd741ee7 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -199,7 +199,7 @@ window.cleanUp = function() { }); fieldsLayer.eachLayer(function(fieldgroup) { fieldgroup.eachLayer(function(item) { - if(!item.options.guid) return true; + if(!item.options.guid) return true; // Skip MU div container as this doesn't have the bounds we need if(b.intersects(item.getBounds())) return; cnt[2]++; fieldsLayer.removeLayer(fieldgroup); @@ -542,13 +542,13 @@ window.renderField = function(ent) { var reg = ent[2].capturedRegion; var latlngs = [ - new L.LatLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), - new L.LatLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), - new L.LatLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) + L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), + L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), + L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; // Curve fit equation to normalize zoom window area - var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()) + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); // Do nothing if zoom did not change. We need to recheck the field if the // zoom level is different then when the field was rendered as it could From 898f0c37ce20a424f707e98d7e7ac9fda6daa452 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 01:21:50 -0800 Subject: [PATCH 8/9] One more nit --- code/map_data.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/map_data.js b/code/map_data.js index dd741ee7..1b885e7d 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -596,7 +596,8 @@ window.renderField = function(ent) { icon: L.divIcon({ className: 'fieldmu', iconSize: [70,12], - html: digits(ent[2].entityScore.entityScore)}), + html: digits(ent[2].entityScore.entityScore) + }), clickable: false }); From 01f7b7099d78401fd064b7bc7940cfba45db3f12 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sun, 3 Mar 2013 19:17:17 -0800 Subject: [PATCH 9/9] Use LineUtil.simplify, rearange some code --- code/map_data.js | 70 +++++++++++++++++++++++++----------------------- main.js | 2 ++ 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/code/map_data.js b/code/map_data.js index 1b885e7d..6dc7f0c9 100644 --- a/code/map_data.js +++ b/code/map_data.js @@ -539,33 +539,18 @@ window.renderLink = function(ent) { window.renderField = function(ent) { if(Object.keys(fields).length >= MAX_DRAWN_FIELDS) return window.removeByGuid(ent[0]); + + var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); + // If this already exists and the zoom level has not changed, we don't need to do anything + if(old && map.getZoom() === old.options.creationZoom) return; + var team = getTeam(ent[2]); var reg = ent[2].capturedRegion; var latlngs = [ L.latLng(reg.vertexA.location.latE6/1E6, reg.vertexA.location.lngE6/1E6), L.latLng(reg.vertexB.location.latE6/1E6, reg.vertexB.location.lngE6/1E6), L.latLng(reg.vertexC.location.latE6/1E6, reg.vertexC.location.lngE6/1E6) ]; - - // Curve fit equation to normalize zoom window area - var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); - - // Do nothing if zoom did not change. We need to recheck the field if the - // zoom level is different then when the field was rendered as it could - // now be appropriate or not to show an MU count - var old = findEntityInLeaflet(fieldsLayer, window.fields, ent[0]); - if(old) { - if(map.getZoom() === old.options.creationZoom) return; - var layerCount = 0; - old.eachLayer(function(item) { - layerCount++; - }); - if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 2) return; - if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && layerCount === 1) return; - removeByGuid(ent[0]); - } - - var team = getTeam(ent[2]); var poly = L.polygon(latlngs, { fillColor: COLORS[team], @@ -587,22 +572,41 @@ window.renderField = function(ent) { if(!getPaddedBounds().intersects(poly.getBounds())) return; - var centroid = [ - (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, - (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 - ]; - - var fieldMu = L.marker(centroid, { - icon: L.divIcon({ - className: 'fieldmu', - iconSize: [70,12], - html: digits(ent[2].entityScore.entityScore) - }), - clickable: false + // Curve fit equation to normalize zoom window area + var areaZoomRatio = calcTriArea(latlngs)/Math.exp(14.2714860198866-1.384987247*map.getZoom()); + var countForMUDisplay = L.LineUtil.simplify(poly._originalPoints, FIELD_MU_DISPLAY_POINT_TOLERANCE).length + + // Do nothing if zoom did not change. We need to recheck the field if the + // zoom level is different then when the field was rendered as it could + // now be appropriate or not to show an MU count + if(old) { + var layerCount = 0; + old.eachLayer(function(item) { + layerCount++; }); + // Don't do anything since we already have an MU display and we still want to + if(areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2 && layerCount === 2) return; + // Don't do anything since we don't have an MU display and don't want to + if(areaZoomRatio <= FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay <= 2 && layerCount === 1) return; + removeByGuid(ent[0]); + } // put both in one group, so they can be handled by the same logic. - if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO) { + if (areaZoomRatio > FIELD_MU_DISPLAY_AREA_ZOOM_RATIO && countForMUDisplay > 2) { + // centroid of field for placing MU count at + var centroid = [ + (latlngs[0].lat + latlngs[1].lat + latlngs[2].lat)/3, + (latlngs[0].lng + latlngs[1].lng + latlngs[2].lng)/3 + ]; + + var fieldMu = L.marker(centroid, { + icon: L.divIcon({ + className: 'fieldmu', + iconSize: [70,12], + html: digits(ent[2].entityScore.entityScore) + }), + clickable: false + }); var f = L.layerGroup([poly, fieldMu]); } else { var f = L.layerGroup([poly]); diff --git a/main.js b/main.js index 04a62374..972b4729 100644 --- a/main.js +++ b/main.js @@ -151,6 +151,8 @@ window.MAX_DRAWN_FIELDS = 200; window.RESONATOR_DISPLAY_ZOOM_LEVEL = 17; // Minimum area to zoom ratio that field MU's will display window.FIELD_MU_DISPLAY_AREA_ZOOM_RATIO = 0.001; +// Point tolerance for displaying MU's +window.FIELD_MU_DISPLAY_POINT_TOLERANCE = 60 window.COLOR_SELECTED_PORTAL = '#f00'; window.COLORS = ['#FFCE00', '#0088FF', '#03DC03']; // none, res, enl