mapshaper 0.6.104 → 0.6.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/mapshaper.js CHANGED
@@ -19290,7 +19290,7 @@
19290
19290
 
19291
19291
  // symType: point, polygon, polyline, label
19292
19292
  function applyStyleAttributes(svgObj, symType, rec, filter) {
19293
- var fields = findPropertiesBySymbolGeom(Object.keys(rec || {}), symType);
19293
+ var fields = findStylePropertiesBySymbolGeom(Object.keys(rec || {}), symType);
19294
19294
  for (var i=0, n=fields.length; i<n; i++) {
19295
19295
  if (filter && !filter(fields[i])) continue;
19296
19296
  setAttribute(svgObj, fields[i], rec[fields[i]]);
@@ -19318,7 +19318,7 @@
19318
19318
  return name in symbolPropertyTypes;
19319
19319
  }
19320
19320
 
19321
- function findPropertiesBySymbolGeom(fields, type) {
19321
+ function findStylePropertiesBySymbolGeom(fields, type) {
19322
19322
  var index = propertiesBySymbolType[type] || {};
19323
19323
  return fields.filter(function(name) {
19324
19324
  return name in index;
@@ -19467,7 +19467,7 @@
19467
19467
  var SvgProperties = /*#__PURE__*/Object.freeze({
19468
19468
  __proto__: null,
19469
19469
  applyStyleAttributes: applyStyleAttributes,
19470
- findPropertiesBySymbolGeom: findPropertiesBySymbolGeom,
19470
+ findStylePropertiesBySymbolGeom: findStylePropertiesBySymbolGeom,
19471
19471
  getSymbolDataAccessor: getSymbolDataAccessor,
19472
19472
  getSymbolPropertyAccessor: getSymbolPropertyAccessor,
19473
19473
  isSupportedSvgStyleProperty: isSupportedSvgStyleProperty,
@@ -46041,7 +46041,7 @@ ${svg}
46041
46041
  });
46042
46042
  }
46043
46043
 
46044
- var version = "0.6.104";
46044
+ var version = "0.6.106";
46045
46045
 
46046
46046
  // Parse command line args into commands and run them
46047
46047
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.104",
3
+ "version": "0.6.106",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -94,5 +94,8 @@
94
94
  "homepage": "https://github.com/mbloch/mapshaper#readme",
95
95
  "directories": {
96
96
  "test": "test"
97
+ },
98
+ "optionalDependencies": {
99
+ "@rollup/rollup-linux-x64-gnu": "^4.44.1"
97
100
  }
98
101
  }
package/www/basemap.js CHANGED
@@ -1,7 +1,8 @@
1
1
  window.mapboxParams = {
2
2
  js: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.js',
3
3
  css: 'https://api.mapbox.com/mapbox-gl-js/v2.11.1/mapbox-gl.css',
4
- key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY2wxMzI4b3dqMDNhMjNpcDhzcmU0aGh5diJ9.m1lacx48pTYls-X3FVhG9g',
4
+ production_key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY21jZ2RlbGk1MGhvNzJrcHV2dTYzZWE2byJ9.btkRnRrPW75c0AlQ5lH2cg',
5
+ localhost_key: 'pk.eyJ1IjoiZ3JhbW1hdGEiLCJhIjoiY21jZ2Rna2hrMGo2ZjJqcHFxMHAycDlyMSJ9.q8FchhB-NAN_FGBHN0AJeg',
5
6
  styles: [{
6
7
  name: 'Map',
7
8
  icon: 'images/thumb-map.jpg',
@@ -1156,7 +1156,7 @@
1156
1156
  }
1157
1157
 
1158
1158
 
1159
- function adjustPointSymbolSizes(layers, overlayLyr, ext) {
1159
+ function calcDotScale(layers, ext) {
1160
1160
  var bbox = ext.getBounds().scale(1.3).toArray(); // add buffer
1161
1161
  // var topTier = 50000; // can be a bottleneck
1162
1162
  var topTier = 10000; // short-circuit counting here
@@ -1180,17 +1180,10 @@
1180
1180
  k *= Math.pow(mapScale, 0.02);
1181
1181
  }
1182
1182
 
1183
-
1184
1183
  // scale down when map is small
1185
1184
  var smallSide = Math.min(ext.width(), ext.height());
1186
1185
  k *= utils$1.clamp(smallSide / 500, 0.5, 1);
1187
-
1188
- layers.forEach(function(lyr) {
1189
- lyr.gui.style.dotScale = k;
1190
- });
1191
- if (overlayLyr && overlayLyr.geometry_type == 'point' && overlayLyr.gui.style.dotSize > 0) {
1192
- overlayLyr.gui.style.dotScale = k;
1193
- }
1186
+ return k;
1194
1187
  }
1195
1188
 
1196
1189
  function countPoints(shapes, max, bbox) {
@@ -2754,350 +2747,6 @@
2754
2747
  return !!lyr?.gui.invertPoint;
2755
2748
  }
2756
2749
 
2757
- var darkStroke = "#334",
2758
- lightStroke = "#b7d9ea",
2759
- violet = "#cc6acc",
2760
- violetFill = "rgba(249, 120, 249, 0.20)",
2761
- gold = "#efc100",
2762
- black = "black",
2763
- grey = "#888",
2764
- selectionFill = "rgba(237, 214, 0, 0.12)",
2765
- hoverFill = "rgba(255, 120, 255, 0.12)",
2766
- activeStyle = { // outline style for the active layer
2767
- type: 'outline',
2768
- strokeColors: [lightStroke, darkStroke],
2769
- strokeWidth: 0.8,
2770
- dotColor: "#223",
2771
- dotSize: 1
2772
- },
2773
- activeStyleDarkMode = {
2774
- type: 'outline',
2775
- strokeColors: [lightStroke, 'white'],
2776
- strokeWidth: 0.9,
2777
- dotColor: 'white',
2778
- dotSize: 1
2779
- },
2780
- activeStyleForLabels = {
2781
- dotColor: "rgba(250, 0, 250, 0.45)", // violet dot with transparency
2782
- dotSize: 1
2783
- },
2784
- referenceStyle = { // outline style for reference layers
2785
- type: 'outline',
2786
- strokeColors: [null, '#78c110'], // upped saturation from #86c927
2787
- strokeWidth: 0.85,
2788
- dotColor: "#73ba20",
2789
- dotSize: 1
2790
- },
2791
- intersectionStyle = {
2792
- dotColor: "#F24400",
2793
- dotSize: 1
2794
- },
2795
- hoverStyles = {
2796
- polygon: {
2797
- fillColor: hoverFill,
2798
- strokeColor: black,
2799
- strokeWidth: 1.2
2800
- }, point: {
2801
- dotColor: violet, // black,
2802
- dotSize: 2.5
2803
- }, polyline: {
2804
- strokeColor: black,
2805
- strokeWidth: 2.5,
2806
- }
2807
- },
2808
- unselectedHoverStyles = {
2809
- polygon: {
2810
- fillColor: 'rgba(0,0,0,0)',
2811
- strokeColor: black,
2812
- strokeWidth: 1.2
2813
- }, point: {
2814
- dotColor: black, // grey,
2815
- dotSize: 2
2816
- }, polyline: {
2817
- strokeColor: black, // grey,
2818
- strokeWidth: 2.5
2819
- }
2820
- },
2821
- selectionStyles = {
2822
- polygon: {
2823
- fillColor: hoverFill,
2824
- strokeColor: black,
2825
- strokeWidth: 1.2
2826
- }, point: {
2827
- dotColor: violet, // black,
2828
- dotSize: 1.5
2829
- }, polyline: {
2830
- strokeColor: violet, // black,
2831
- strokeWidth: 2.5
2832
- }
2833
- },
2834
- // not used
2835
- selectionHoverStyles = {
2836
- polygon: {
2837
- fillColor: selectionFill,
2838
- strokeColor: black,
2839
- strokeWidth: 1.2
2840
- }, point: {
2841
- dotColor: black,
2842
- dotSize: 1.5
2843
- }, polyline: {
2844
- strokeColor: black,
2845
- strokeWidth: 2
2846
- }
2847
- },
2848
- pinnedStyles = {
2849
- polygon: {
2850
- fillColor: violetFill,
2851
- strokeColor: violet,
2852
- strokeWidth: 1.8
2853
- }, point: {
2854
- dotColor: violet,
2855
- dotSize: 3
2856
- }, polyline: {
2857
- strokeColor: violet, // black, // violet,
2858
- strokeWidth: 3
2859
- }
2860
- };
2861
-
2862
- function getIntersectionStyle(lyr, opts) {
2863
- return getDefaultStyle(lyr, intersectionStyle);
2864
- }
2865
-
2866
- // Display style for unselected layers with visibility turned on
2867
- // (may be fully styled or outlined)
2868
- function getReferenceLayerStyle(lyr, opts) {
2869
- var style;
2870
- if (layerHasCanvasDisplayStyle(lyr) && !opts.outlineMode) {
2871
- style = getCanvasDisplayStyle(lyr);
2872
- } else if (internal.layerHasLabels(lyr) && !opts.outlineMode) {
2873
- style = {dotSize: 0}; // no reference dots if labels are visible
2874
- } else {
2875
- style = getDefaultStyle(lyr, referenceStyle);
2876
- }
2877
- return style;
2878
- }
2879
-
2880
- function getActiveLayerStyle(lyr, opts) {
2881
- var style;
2882
- if (layerHasCanvasDisplayStyle(lyr) && !opts.outlineMode) {
2883
- style = getCanvasDisplayStyle(lyr);
2884
- } else if (internal.layerHasLabels(lyr) && !opts.outlineMode) {
2885
- style = getDefaultStyle(lyr, activeStyleForLabels);
2886
- } else if (opts.darkMode) {
2887
- style = getDefaultStyle(lyr, activeStyleDarkMode);
2888
- } else {
2889
- style = getDefaultStyle(lyr, activeStyle);
2890
- }
2891
- return style;
2892
- }
2893
-
2894
- // Returns a display style for the overlay layer.
2895
- // The overlay layer renders several kinds of feature, each of which is displayed
2896
- // with a different style.
2897
- //
2898
- // * hover shapes
2899
- // * selected shapes
2900
- // * pinned shapes
2901
- //
2902
- function getOverlayStyle(baseLyr, o, opts) {
2903
- if (opts.interactionMode == 'vertices') {
2904
- return getVertexStyle(baseLyr, o);
2905
- }
2906
- if (opts.interactionMode == 'edit_lines' ||
2907
- opts.interactionMode == 'edit_polygons') {
2908
- return getLineEditingStyle(o);
2909
- }
2910
- var geomType = baseLyr.geometry_type;
2911
- var topId = o.id; // pinned id (if pinned) or hover id
2912
- var topIdx = -1;
2913
- var styler = function(style, i) {
2914
- var defaultStyle = i === topIdx ? topStyle : outlineStyle;
2915
- if (baseStyle.styler) {
2916
- // TODO: render default stroke widths without scaling
2917
- // (will need to pass symbol scale to the styler function)
2918
- style.strokeWidth = defaultStyle.strokeWidth;
2919
- baseStyle.styler(style, i); // get styled stroke width (if set)
2920
- style.strokeColor = defaultStyle.strokeColor;
2921
- style.fillColor = defaultStyle.fillColor;
2922
- } else {
2923
- Object.assign(style, defaultStyle);
2924
- }
2925
- };
2926
- var baseStyle = getActiveLayerStyle(baseLyr, opts);
2927
- var outlineStyle = getDefaultStyle(baseLyr, selectionStyles[geomType]);
2928
- var topStyle;
2929
- var ids = o.ids.filter(function(i) {
2930
- return i != o.id; // move selected id to the end
2931
- });
2932
- if (o.id > -1) { // pinned or hover style
2933
- topStyle = getSelectedFeatureStyle(baseLyr, o, opts);
2934
- topIdx = ids.length;
2935
- ids.push(o.id); // put the pinned/hover feature last in the render order
2936
- }
2937
- var style = {
2938
- baseStyle: baseStyle,
2939
- styler,
2940
- ids,
2941
- overlay: true
2942
- };
2943
-
2944
- if (layerHasCanvasDisplayStyle(baseLyr) && !opts.outlineMode) {
2945
- if (geomType == 'point') {
2946
- style.styler = getOverlayPointStyler(getCanvasDisplayStyle(baseLyr).styler, styler);
2947
- }
2948
- style.type = 'styled';
2949
-
2950
- }
2951
- return ids.length > 0 ? style : null;
2952
- }
2953
-
2954
-
2955
- function getDefaultStyle(lyr, baseStyle) {
2956
- return Object.assign({}, baseStyle);
2957
- }
2958
-
2959
-
2960
- // style for vertex edit mode
2961
- function getVertexStyle(lyr, o) {
2962
- return {
2963
- ids: o.ids,
2964
- overlay: true,
2965
- strokeColor: black,
2966
- strokeWidth: 1.5,
2967
- vertices: true,
2968
- vertex_overlay: o.hit_coordinates || null,
2969
- selected_points: o.selected_points || null,
2970
- fillColor: null
2971
- };
2972
- }
2973
-
2974
- // style for vertex edit mode
2975
- function getLineEditingStyle(o) {
2976
- return {
2977
- ids: o.ids,
2978
- overlay: true,
2979
- strokeColor: 'black',
2980
- strokeWidth: 1.2,
2981
- vertices: true,
2982
- vertex_overlay_color: o.hit_type == 'vertex' ? violet : black,
2983
- vertex_overlay_scale: o.hit_type == 'vertex' ? 2.5 : 2,
2984
- vertex_overlay: o.hit_coordinates || null,
2985
- selected_points: o.selected_points || null,
2986
- fillColor: null
2987
- };
2988
- }
2989
-
2990
-
2991
- function getSelectedFeatureStyle(lyr, o, opts) {
2992
- var isPinned = o.pinned;
2993
- var inSelection = o.ids.indexOf(o.id) > -1;
2994
- var geomType = lyr.geometry_type;
2995
- var style;
2996
- if (isPinned && opts.interactionMode == 'rectangles') {
2997
- // kludge for rectangle editing mode
2998
- style = selectionStyles[geomType];
2999
- } else if (isPinned) {
3000
- // a feature is pinned
3001
- style = pinnedStyles[geomType];
3002
- } else if (inSelection) {
3003
- // normal hover, or hover id is in the selection set
3004
- style = hoverStyles[geomType];
3005
- } else {
3006
- // features are selected, but hover id is not in the selection set
3007
- style = unselectedHoverStyles[geomType];
3008
- }
3009
- return getDefaultStyle(lyr, style);
3010
- }
3011
-
3012
- // Modify style to use scaled circle instead of dot symbol
3013
- function getOverlayPointStyler(baseStyler, overlayStyler) {
3014
- return function(obj, i) {
3015
- var dotColor;
3016
- var id = obj.ids ? obj.ids[i] : -1;
3017
- obj.strokeWidth = 0; // kludge to support setting minimum stroke width
3018
- baseStyler(obj, id);
3019
- if (overlayStyler) {
3020
- overlayStyler(obj, i);
3021
- }
3022
- dotColor = obj.dotColor;
3023
- if (obj.radius && dotColor) {
3024
- obj.radius += 0.4;
3025
- // delete obj.fillColor; // only show outline
3026
- obj.fillColor = dotColor; // comment out to only highlight stroke
3027
- obj.strokeColor = dotColor;
3028
- obj.strokeWidth = Math.max(obj.strokeWidth + 0.8, 1.5);
3029
- obj.opacity = 1;
3030
- }
3031
- };
3032
- }
3033
-
3034
- function getCanvasDisplayStyle(lyr) {
3035
- var styleIndex = {
3036
- opacity: 'opacity',
3037
- r: 'radius',
3038
- 'fill': 'fillColor',
3039
- 'fill-pattern': 'fillPattern',
3040
- 'fill-effect': 'fillEffect',
3041
- 'fill-opacity': 'fillOpacity',
3042
- 'stroke': 'strokeColor',
3043
- 'stroke-width': 'strokeWidth',
3044
- 'stroke-dasharray': 'lineDash',
3045
- 'stroke-opacity': 'strokeOpacity',
3046
- 'stroke-linecap': 'lineCap',
3047
- 'stroke-linejoin': 'lineJoin',
3048
- 'stroke-miterlimit': 'miterLimit'
3049
- },
3050
- // array of field names of relevant svg display properties
3051
- fields = getCanvasStyleFields(lyr).filter(function(f) {return f in styleIndex;}),
3052
- records = lyr.data.getRecords();
3053
-
3054
- var styler = function(style, i) {
3055
- var rec = records[i];
3056
- var fname, val;
3057
- for (var j=0; j<fields.length; j++) {
3058
- fname = fields[j];
3059
- val = rec && rec[fname];
3060
- if (val == 'none') {
3061
- val = 'transparent'; // canvas equivalent of CSS 'none'
3062
- }
3063
- // convert svg property name to mapshaper style equivalent
3064
- style[styleIndex[fname]] = val;
3065
- }
3066
-
3067
- if (style.strokeWidth && !style.strokeColor) {
3068
- style.strokeColor = 'black';
3069
- }
3070
- if (!('strokeWidth' in style) && style.strokeColor) {
3071
- style.strokeWidth = 1;
3072
- }
3073
- if (style.radius > 0 && !style.strokeWidth && !style.fillColor && lyr.geometry_type == 'point') {
3074
- style.fillColor = 'black';
3075
- }
3076
- };
3077
- var style = {styler: styler, type: 'styled'};
3078
- // use squares if radius is missing... (TODO: check behavior with labels, etc)
3079
- if (lyr.geometry_type == 'point' && fields.includes('r') === false) {
3080
- style.dotSize = 1;
3081
- }
3082
- return style;
3083
- }
3084
-
3085
- // check if layer should be displayed with a full style
3086
- function layerHasCanvasDisplayStyle(lyr) {
3087
- var fields = getCanvasStyleFields(lyr);
3088
- if (lyr.geometry_type == 'point') {
3089
- // return fields.indexOf('r') > -1; // require 'r' field for point symbols
3090
- return fields.includes('fill') || fields.includes('r'); // support colored squares
3091
- }
3092
- return utils$1.difference(fields, ['opacity', 'class']).length > 0;
3093
- }
3094
-
3095
-
3096
- function getCanvasStyleFields(lyr) {
3097
- var fields = lyr.data ? lyr.data.getFields() : [];
3098
- return internal.findPropertiesBySymbolGeom(fields, lyr.geometry_type);
3099
- }
3100
-
3101
2750
  // Create low-detail versions of large arc collections for faster rendering
3102
2751
  // at zoomed-out scales.
3103
2752
  function enhanceArcCollectionForDisplay(unfilteredArcs) {
@@ -8228,7 +7877,7 @@
8228
7877
  }
8229
7878
  });
8230
7879
  return {
8231
- ids: hits
7880
+ ids: utils$1.uniq(hits)
8232
7881
  };
8233
7882
  };
8234
7883
  }
@@ -8414,7 +8063,7 @@
8414
8063
  mouse.on('contextmenu', function(e) {
8415
8064
  e.originalEvent.preventDefault();
8416
8065
  if (El('body').hasClass('map-view')) {
8417
- triggerHitEvent('contextmenu', e);
8066
+ triggerPointerEvent('contextmenu', e);
8418
8067
  }
8419
8068
  });
8420
8069
 
@@ -8510,7 +8159,7 @@
8510
8159
  if (storedData.id == id) return;
8511
8160
  storedData.id = id;
8512
8161
  storedData.ids = id == -1 ? [] : [id];
8513
- triggerHitEvent('change');
8162
+ triggerChangeEvent();
8514
8163
  };
8515
8164
 
8516
8165
  // Get a reference to the active layer, so listeners to hit events can interact
@@ -8529,7 +8178,7 @@
8529
8178
  self.setPinning = function(val) {
8530
8179
  if (pinnedOn != val) {
8531
8180
  pinnedOn = val;
8532
- triggerHitEvent('change');
8181
+ triggerChangeEvent();
8533
8182
  }
8534
8183
  };
8535
8184
 
@@ -8537,7 +8186,7 @@
8537
8186
  // turnOn('selection');
8538
8187
  transientIds = ids || [];
8539
8188
  if (active) {
8540
- triggerHitEvent('change');
8189
+ triggerChangeEvent();
8541
8190
  }
8542
8191
  };
8543
8192
 
@@ -8552,9 +8201,9 @@
8552
8201
  self.triggerChangeEvent();
8553
8202
  };
8554
8203
 
8555
- self.triggerChangeEvent = function() {
8556
- triggerHitEvent('change');
8557
- };
8204
+ self.triggerChangeEvent = triggerChangeEvent;
8205
+
8206
+ self.getHitState = getHitState;
8558
8207
 
8559
8208
  self.clearDrawingId = function() {
8560
8209
  self.setDrawingId(-1);
@@ -8566,14 +8215,14 @@
8566
8215
  if (p2 && p2[0] == p[0] && p2[1] == p[1]) return;
8567
8216
  storedData.hit_coordinates = p;
8568
8217
  storedData.hit_type = type || '';
8569
- triggerHitEvent('change');
8218
+ triggerChangeEvent();
8570
8219
  };
8571
8220
 
8572
8221
  self.clearHoverVertex = function() {
8573
8222
  if (!storedData.hit_coordinates) return;
8574
8223
  delete storedData.hit_coordinates;
8575
8224
  delete storedData.hit_type;
8576
- triggerHitEvent('change');
8225
+ triggerChangeEvent();
8577
8226
  };
8578
8227
 
8579
8228
  self.clearSelection = function() {
@@ -8607,7 +8256,7 @@
8607
8256
  if (n < 2 || pinnedId() == -1) return;
8608
8257
  storedData.id = (pinnedId() + n + diff) % n;
8609
8258
  storedData.ids = [storedData.id];
8610
- triggerHitEvent('change');
8259
+ triggerChangeEvent();
8611
8260
  }
8612
8261
 
8613
8262
  // diff: 1 or -1
@@ -8617,7 +8266,7 @@
8617
8266
  var n = storedData.ids.length;
8618
8267
  if (i < 0 || n < 2) return;
8619
8268
  storedData.id = storedData.ids[(i + diff + n) % n];
8620
- triggerHitEvent('change');
8269
+ triggerChangeEvent();
8621
8270
  }
8622
8271
 
8623
8272
  // make sure popup is unpinned and turned off when switching editing modes
@@ -8644,7 +8293,6 @@
8644
8293
  mouse.on('drag', handlePointerEvent, null, priority);
8645
8294
  mouse.on('dragend', handlePointerEvent, null, priority);
8646
8295
 
8647
-
8648
8296
  mouse.on('click', function(e) {
8649
8297
  var pinned = storedData.pinned;
8650
8298
  if (!hitTest || !active) return;
@@ -8661,7 +8309,7 @@
8661
8309
  // a new point doesn't get made
8662
8310
  return;
8663
8311
  }
8664
- triggerHitEvent('click', e);
8312
+ triggerPointerEvent('click', e);
8665
8313
  }, null, priority);
8666
8314
 
8667
8315
  // Hits are re-detected on 'hover' (if hit detection is active)
@@ -8775,7 +8423,7 @@
8775
8423
  storedData = newData;
8776
8424
  gui.container.findChild('.map-layers').classed('symbol-hit', nonEmpty);
8777
8425
  if (active) {
8778
- triggerHitEvent('change');
8426
+ triggerChangeEvent();
8779
8427
  }
8780
8428
  }
8781
8429
 
@@ -8827,40 +8475,50 @@
8827
8475
  function handlePointerEvent(e) {
8828
8476
  if (eventIsEnabled(e.type)) {
8829
8477
  possiblyStopPropagation(e);
8830
- triggerHitEvent(e.type, e);
8478
+ triggerPointerEvent(e.type, e);
8831
8479
  }
8832
8480
  }
8833
8481
 
8482
+ function triggerChangeEvent() {
8483
+ self.dispatchEvent('change', getHitState());
8484
+ }
8485
+
8834
8486
  // evt: event data (may be a pointer event object, an ordinary object or null)
8835
- function triggerHitEvent(type, evt) {
8836
- var eventData = {
8837
- mode: interactionMode()
8838
- };
8487
+ function triggerPointerEvent(type, evt) {
8488
+ var eventData = getHitState();
8839
8489
  if (evt) {
8840
8490
  // data coordinates
8841
8491
  eventData.projected_coordinates = gui.map.pixelCoordsToProjectedCoords(evt.x, evt.y);
8842
8492
  eventData.lonlat_coordinates = gui.map.pixelCoordsToLngLatCoords(evt.x, evt.y);
8843
8493
  eventData.originalEvent = evt;
8844
8494
  eventData.overMap = isOverMap(evt);
8495
+ utils$1.defaults(eventData, evt.data);
8845
8496
  }
8497
+ // utils.defaults(eventData, evt && evt.data || {}, storedData);
8498
+ self.dispatchEvent(type, eventData);
8499
+ }
8500
+
8501
+ function getHitState() {
8502
+ var data = {
8503
+ mode: interactionMode()
8504
+ };
8846
8505
  // Merge stored hit data into the event data
8847
- utils$1.defaults(eventData, evt && evt.data || {}, storedData);
8848
- // utils.extend(eventData, storedData);
8506
+ utils$1.defaults(data, storedData);
8849
8507
  if (transientIds.length) {
8850
8508
  // add transient ids to any other hit ids
8851
- eventData.ids = utils$1.uniq(transientIds.concat(eventData.ids || []));
8509
+ data.ids = utils$1.uniq(transientIds.concat(data.ids || []));
8852
8510
  }
8853
8511
  // when drawing, we want the overlay layer to show the path being currently
8854
8512
  // drawn.
8855
8513
  if (drawingId >= 0) {
8856
- // eventData.ids = [drawingId];
8857
- // eventData.id = drawingId;
8858
- eventData.ids = utils$1.uniq(eventData.ids.concat([drawingId]));
8514
+ // data.ids = [drawingId];
8515
+ // data.id = drawingId;
8516
+ data.ids = utils$1.uniq(data.ids.concat([drawingId]));
8859
8517
  }
8860
8518
  if (pinnedOn) {
8861
- eventData.pinned = true;
8519
+ data.pinned = true;
8862
8520
  }
8863
- self.dispatchEvent(type, eventData);
8521
+ return data;
8864
8522
  }
8865
8523
 
8866
8524
  // Test if two hit data objects are equivalent
@@ -10290,74 +9948,279 @@
10290
9948
  }
10291
9949
 
10292
9950
 
10293
- function getFieldType(val, key, table) {
10294
- // if a field has a null value, look at entire column to identify type
10295
- return internal.getValueType(val) || internal.getColumnType(key, table.getRecords()) ;
9951
+ function getFieldType(val, key, table) {
9952
+ // if a field has a null value, look at entire column to identify type
9953
+ return internal.getValueType(val) || internal.getColumnType(key, table.getRecords()) ;
9954
+ }
9955
+
9956
+ function InspectionControl2(gui, hit) {
9957
+ var _popup = new Popup(gui, hit.getSwitchTrigger(1), hit.getSwitchTrigger(-1));
9958
+ var _self = new EventDispatcher();
9959
+
9960
+ gui.on('interaction_mode_change', function(e) {
9961
+ if (!gui.interaction.modeUsesPopup(e.mode)) {
9962
+ inspect(-1); // clear the popup
9963
+ }
9964
+ });
9965
+
9966
+ _popup.on('data_updated', function(e) {
9967
+ // data_change event no longer needed (update is handled below)
9968
+ // _self.dispatchEvent('data_change', e.data); // let map know which field has changed
9969
+ gui.session.dataValueUpdated(e.ids, e.field, e.value);
9970
+ // Refresh the display if a style variable has been changed interactively
9971
+ if (internal.isSupportedSvgStyleProperty(e.field)) {
9972
+ gui.dispatchEvent('map-needs-refresh');
9973
+ }
9974
+ });
9975
+
9976
+ hit.on('contextmenu', function(e) {
9977
+ if (!e.overMap || e.mode == 'edit_lines' || e.mode == 'edit_polygons' ||
9978
+ e.mode == 'edit_points') {
9979
+ return;
9980
+ }
9981
+ var target = hit.getHitTarget();
9982
+ if (e.ids.length == 1) {
9983
+ e.deleteFeature = function() {
9984
+ deleteFeature(target, e.ids[0]);
9985
+ gui.model.updated({filter:true});
9986
+ };
9987
+ }
9988
+ gui.contextMenu.open(e, target);
9989
+ });
9990
+
9991
+ hit.on('change', function(e) {
9992
+ if (!inspecting()) return;
9993
+ if (gui.keyboard.ctrlIsPressed()) return;
9994
+ var ids;
9995
+ if (e.mode == 'selection') {
9996
+ ids = e.pinned && e.ids || [];
9997
+ } else {
9998
+ ids = e.ids || [];
9999
+ }
10000
+ inspect(e.id, ids, e.pinned);
10001
+ });
10002
+
10003
+ // id: Id of a feature in the active layer, or -1
10004
+ function inspect(id, ids, pin) {
10005
+ var target = hit.getHitTarget();
10006
+ if ((id > -1 || ids && ids.length > 0) && inspecting() && target && target) {
10007
+ _popup.show(id, ids, target, pin);
10008
+ } else {
10009
+ _popup.hide();
10010
+ }
10011
+ }
10012
+
10013
+ // does the attribute inspector appear on rollover
10014
+ function inspecting() {
10015
+ return gui.interaction && gui.interaction.modeUsesPopup(gui.interaction.getMode());
10016
+ }
10017
+
10018
+ return _self;
10019
+ }
10020
+
10021
+ var selectionFill = "rgba(237, 214, 0, 0.12)",
10022
+ // hoverFill = "rgba(255, 120, 255, 0.12)",
10023
+ hoverFill = "rgba(0, 0, 0, 0.08)",
10024
+ grey = "#888",
10025
+ violet = "#cc6acc",
10026
+ black = 'black',
10027
+ violetFill = "rgba(249, 120, 249, 0.25)",
10028
+ hoverStyles = {
10029
+ polygon: {
10030
+ fillColor: hoverFill,
10031
+ strokeColor: black,
10032
+ strokeWidth: 1.2
10033
+ }, point: {
10034
+ dotColor: black, // violet, // black,
10035
+ dotSize: 2.5
10036
+ }, polyline: {
10037
+ strokeColor: black,
10038
+ strokeWidth: 2,
10039
+ }
10040
+ },
10041
+ unselectedHoverStyles = {
10042
+ polygon: {
10043
+ fillColor: 'rgba(0,0,0,0)',
10044
+ strokeColor: black,
10045
+ strokeWidth: 1.2
10046
+ }, point: {
10047
+ dotColor: black, // grey,
10048
+ dotSize: 2
10049
+ }, polyline: {
10050
+ strokeColor: black, // grey,
10051
+ strokeWidth: 2.5
10052
+ }
10053
+ },
10054
+ selectionStyles = {
10055
+ polygon: {
10056
+ fillColor: hoverFill,
10057
+ strokeColor: black,
10058
+ strokeWidth: 1.2
10059
+ }, point: {
10060
+ dotColor: violet, // black,
10061
+ dotSize: 1.5
10062
+ }, polyline: {
10063
+ strokeColor: violet, // black,
10064
+ strokeWidth: 2.5
10065
+ }
10066
+ },
10067
+ // currently not used -- selection hover is not styled
10068
+ selectionHoverStyles = {
10069
+ polygon: {
10070
+ fillColor: selectionFill,
10071
+ strokeColor: black,
10072
+ strokeWidth: 1.2
10073
+ }, point: {
10074
+ dotColor: black,
10075
+ dotSize: 1.5
10076
+ }, polyline: {
10077
+ strokeColor: black,
10078
+ strokeWidth: 2
10079
+ }
10080
+ },
10081
+ pinnedStyles = {
10082
+ polygon: {
10083
+ fillColor: violetFill,
10084
+ strokeColor: violet,
10085
+ strokeWidth: 1.8
10086
+ }, point: {
10087
+ dotColor: violet,
10088
+ dotSize: 3
10089
+ }, polyline: {
10090
+ strokeColor: violet,
10091
+ strokeWidth: 2.4
10092
+ }
10093
+ };
10094
+
10095
+ function getOverlayLayers(activeLyr, hitData, styleOpts) {
10096
+ if (activeLyr.hidden || !activeLyr?.gui?.style) return [];
10097
+ var displayLyr = activeLyr.gui.displayLayer;
10098
+ var layers, lyr, outlineStyle, ids;
10099
+ if (styleOpts.interactionMode == 'vertices') {
10100
+ // special overlay: vertex editing mode
10101
+ lyr = getOverlayLayer(activeLyr, hitData.ids);
10102
+ lyr.gui.style = getVertexStyle(hitData);
10103
+ return [lyr];
10104
+ }
10105
+ if (styleOpts.interactionMode == 'edit_lines' ||
10106
+ styleOpts.interactionMode == 'edit_polygons') {
10107
+ // special overlay: shape editing mode
10108
+ lyr = getOverlayLayer(activeLyr, hitData.ids);
10109
+ lyr.gui.style = getLineEditingStyle(hitData);
10110
+ return [lyr];
10111
+ }
10112
+ layers = [];
10113
+ // layer containing selected features, not including hover or pinned feature
10114
+ ids = utils$1.difference(hitData.ids || [], [hitData.id]);
10115
+ if (ids.length > 0) {
10116
+ lyr = getOverlayLayer(activeLyr, ids);
10117
+ outlineStyle = selectionStyles[displayLyr.geometry_type];
10118
+ lyr.gui.style = getOverlayStyle(activeLyr, ids, outlineStyle);
10119
+ layers.push(lyr);
10120
+ }
10121
+ // layer containing a single hover or pinned feature
10122
+ if (hitData.id > -1) {
10123
+ ids = [hitData.id];
10124
+ lyr = getOverlayLayer(activeLyr, ids);
10125
+ outlineStyle = getSelectedFeatureStyle(displayLyr, hitData, styleOpts);
10126
+ lyr.gui.style = getOverlayStyle(activeLyr, ids, outlineStyle);
10127
+ layers.push(lyr);
10128
+ }
10129
+ return layers;
10296
10130
  }
10297
10131
 
10298
- function InspectionControl2(gui, hit) {
10299
- var _popup = new Popup(gui, hit.getSwitchTrigger(1), hit.getSwitchTrigger(-1));
10300
- var _self = new EventDispatcher();
10301
-
10302
- gui.on('interaction_mode_change', function(e) {
10303
- if (!gui.interaction.modeUsesPopup(e.mode)) {
10304
- inspect(-1); // clear the popup
10305
- }
10306
- });
10307
-
10308
- _popup.on('data_updated', function(e) {
10309
- // data_change event no longer needed (update is handled below)
10310
- // _self.dispatchEvent('data_change', e.data); // let map know which field has changed
10311
- gui.session.dataValueUpdated(e.ids, e.field, e.value);
10312
- // Refresh the display if a style variable has been changed interactively
10313
- if (internal.isSupportedSvgStyleProperty(e.field)) {
10314
- gui.dispatchEvent('map-needs-refresh');
10315
- }
10316
- });
10132
+ function getOverlayLayer(activeLyr, ids) {
10133
+ var displayLayer = filterLayerByIds(activeLyr.gui.displayLayer, ids);
10134
+ var gui = Object.assign({}, activeLyr.gui, {style: null, displayLayer});
10135
+ return Object.assign({}, activeLyr, {gui});
10136
+ }
10317
10137
 
10318
- hit.on('contextmenu', function(e) {
10319
- if (!e.overMap || e.mode == 'edit_lines' || e.mode == 'edit_polygons' ||
10320
- e.mode == 'edit_points') {
10138
+ function getOverlayStyle(baseLyr, ids, outlineStyle) {
10139
+ var geomType = baseLyr.gui.displayLayer.geometry_type;
10140
+ var baseStyle = baseLyr.gui.style;
10141
+ var baseStyler = baseStyle.styler || null;
10142
+ var styler = function(style, i) {
10143
+ if (!baseStyler) {
10144
+ // e.g. polygons in 'outline' mode
10145
+ Object.assign(style, outlineStyle);
10321
10146
  return;
10322
10147
  }
10323
- var target = hit.getHitTarget();
10324
- if (e.ids.length == 1) {
10325
- e.deleteFeature = function() {
10326
- deleteFeature(target, e.ids[0]);
10327
- gui.model.updated({filter:true});
10328
- };
10329
- }
10330
- gui.contextMenu.open(e, target);
10331
- });
10332
-
10333
- hit.on('change', function(e) {
10334
- if (!inspecting()) return;
10335
- if (gui.keyboard.ctrlIsPressed()) return;
10336
- var ids;
10337
- if (e.mode == 'selection') {
10338
- ids = e.pinned && e.ids || [];
10339
- } else {
10340
- ids = e.ids || [];
10341
- }
10342
- inspect(e.id, ids, e.pinned);
10343
- });
10344
-
10345
- // id: Id of a feature in the active layer, or -1
10346
- function inspect(id, ids, pin) {
10347
- var target = hit.getHitTarget();
10348
- if ((id > -1 || ids && ids.length > 0) && inspecting() && target && target) {
10349
- _popup.show(id, ids, target, pin);
10148
+ var idx = ids[i];
10149
+ baseStyler(style, idx);
10150
+ if (geomType == 'point') {
10151
+ if (style.radius > 0) {
10152
+ style.radius += 0.8;
10153
+ if (style.strokeWidth > 0) {
10154
+ style.strokeColor = outlineStyle.dotColor;
10155
+ }
10156
+ }
10157
+ style.fillColor = outlineStyle.dotColor;
10350
10158
  } else {
10351
- _popup.hide();
10159
+ style.strokeColor = outlineStyle.strokeColor;
10160
+ style.fillColor = outlineStyle.fillColor;
10161
+ style.strokeWidth = Math.max(outlineStyle.strokeWidth, style.strokeWidth || 0);
10352
10162
  }
10163
+ style.opacity = 1;
10164
+ style.fillOpacity = 1;
10165
+ style.strokeOpacity = 1;
10166
+ };
10167
+ var style = Object.assign({}, baseStyle, {ids, overlay: true, type: 'styled', styler});
10168
+ if (baseStyle.dotSize > 0) {
10169
+ // dot size must be a static property (not applied by styler function)
10170
+ style.dotSize = outlineStyle.dotSize;
10353
10171
  }
10172
+ return style;
10173
+ }
10354
10174
 
10355
- // does the attribute inspector appear on rollover
10356
- function inspecting() {
10357
- return gui.interaction && gui.interaction.modeUsesPopup(gui.interaction.getMode());
10358
- }
10175
+ // style for vertex edit mode
10176
+ function getVertexStyle(o) {
10177
+ return {
10178
+ ids: o.ids,
10179
+ overlay: true,
10180
+ strokeColor: black,
10181
+ strokeWidth: 1.5,
10182
+ vertices: true,
10183
+ vertex_overlay: o.hit_coordinates || null,
10184
+ selected_points: o.selected_points || null,
10185
+ fillColor: null
10186
+ };
10187
+ }
10359
10188
 
10360
- return _self;
10189
+ // style for vertex edit mode
10190
+ function getLineEditingStyle(o) {
10191
+ return {
10192
+ ids: o.ids,
10193
+ overlay: true,
10194
+ strokeColor: black,
10195
+ strokeWidth: 1.2,
10196
+ vertices: true,
10197
+ vertex_overlay_color: o.hit_type == 'vertex' ? violet : black,
10198
+ vertex_overlay_scale: o.hit_type == 'vertex' ? 2.5 : 2,
10199
+ vertex_overlay: o.hit_coordinates || null,
10200
+ selected_points: o.selected_points || null,
10201
+ fillColor: null
10202
+ };
10203
+ }
10204
+
10205
+ function getSelectedFeatureStyle(lyr, o, opts) {
10206
+ var isPinned = o.pinned;
10207
+ var inSelection = o.ids.indexOf(o.id) > -1;
10208
+ var geomType = lyr.geometry_type;
10209
+ var style;
10210
+ if (isPinned && opts.interactionMode == 'rectangles') {
10211
+ // kludge for rectangle editing mode
10212
+ style = selectionStyles[geomType];
10213
+ } else if (isPinned) {
10214
+ // a feature is pinned
10215
+ style = pinnedStyles[geomType];
10216
+ } else if (inSelection) {
10217
+ // normal hover, or hover id is in the selection set
10218
+ style = hoverStyles[geomType];
10219
+ } else {
10220
+ // features are selected, but hover id is not in the selection set
10221
+ style = unselectedHoverStyles[geomType];
10222
+ }
10223
+ return Object.assign({}, style);
10361
10224
  }
10362
10225
 
10363
10226
  function isMultilineLabel(textNode) {
@@ -11391,6 +11254,141 @@
11391
11254
  initLineEditing(gui, ext, hit);
11392
11255
  }
11393
11256
 
11257
+ var darkStroke = "#334",
11258
+ lightStroke = "#b7d9ea",
11259
+ activeStyle = { // outline style for the active layer
11260
+ type: 'outline',
11261
+ strokeColors: [lightStroke, darkStroke],
11262
+ strokeWidth: 0.8,
11263
+ dotColor: "#223",
11264
+ dotSize: 1
11265
+ },
11266
+ activeStyleDarkMode = {
11267
+ type: 'outline',
11268
+ strokeColors: [lightStroke, 'white'],
11269
+ strokeWidth: 0.9,
11270
+ dotColor: 'white',
11271
+ dotSize: 1
11272
+ },
11273
+ activeStyleForLabels = {
11274
+ dotColor: "rgba(250, 0, 250, 0.45)", // violet dot with transparency
11275
+ dotSize: 1
11276
+ },
11277
+ referenceStyle = { // outline style for reference layers
11278
+ type: 'outline',
11279
+ strokeColors: [null, '#78c110'], // upped saturation from #86c927
11280
+ strokeWidth: 0.85,
11281
+ dotColor: "#73ba20",
11282
+ dotSize: 1
11283
+ },
11284
+ intersectionStyle = {
11285
+ dotColor: "#F24400",
11286
+ dotSize: 1
11287
+ };
11288
+
11289
+ function getIntersectionStyle(lyr, opts) {
11290
+ return copyBaseStyle(intersectionStyle);
11291
+ }
11292
+
11293
+ // Display style for unselected layers with visibility turned on
11294
+ // (may be fully styled or outlined)
11295
+ function getReferenceLayerStyle(lyr, opts) {
11296
+ var style;
11297
+ if (layerHasDrawableStyle(lyr) && !opts.outlineMode) {
11298
+ // TODO: consider just copying lyr style
11299
+ style = getCanvasDisplayStyle(lyr);
11300
+ } else if (internal.layerHasLabels(lyr) && !opts.outlineMode) {
11301
+ style = {dotSize: 0}; // no reference dots if labels are visible
11302
+ } else {
11303
+ style = copyBaseStyle(referenceStyle);
11304
+ }
11305
+ return style;
11306
+ }
11307
+
11308
+ function getActiveLayerStyle(lyr, opts) {
11309
+ var style;
11310
+ if (layerHasDrawableStyle(lyr) && !opts.outlineMode) {
11311
+ style = getCanvasDisplayStyle(lyr);
11312
+ } else if (internal.layerHasLabels(lyr) && !opts.outlineMode) {
11313
+ style = copyBaseStyle(activeStyleForLabels);
11314
+ } else if (opts.darkMode) {
11315
+ style = copyBaseStyle(activeStyleDarkMode);
11316
+ } else {
11317
+ style = copyBaseStyle(activeStyle);
11318
+ }
11319
+ return style;
11320
+ }
11321
+
11322
+ function copyBaseStyle(baseStyle) {
11323
+ return Object.assign({}, baseStyle);
11324
+ }
11325
+
11326
+ function getCanvasDisplayStyle(lyr) {
11327
+ var styleIndex = {
11328
+ opacity: 'opacity',
11329
+ r: 'radius',
11330
+ 'fill': 'fillColor',
11331
+ 'fill-pattern': 'fillPattern',
11332
+ 'fill-effect': 'fillEffect',
11333
+ 'fill-opacity': 'fillOpacity',
11334
+ 'stroke': 'strokeColor',
11335
+ 'stroke-width': 'strokeWidth',
11336
+ 'stroke-dasharray': 'lineDash',
11337
+ 'stroke-opacity': 'strokeOpacity',
11338
+ 'stroke-linecap': 'lineCap',
11339
+ 'stroke-linejoin': 'lineJoin',
11340
+ 'stroke-miterlimit': 'miterLimit'
11341
+ },
11342
+ // array of field names of relevant svg display properties
11343
+ fields = getStyleFields(lyr).filter(function(f) {return f in styleIndex;}),
11344
+ records = lyr.data.getRecords();
11345
+
11346
+ var styler = function(style, i) {
11347
+ var rec = records[i];
11348
+ var fname, val;
11349
+ for (var j=0; j<fields.length; j++) {
11350
+ fname = fields[j];
11351
+ val = rec && rec[fname];
11352
+ if (val == 'none') {
11353
+ val = 'transparent'; // canvas equivalent of CSS 'none'
11354
+ }
11355
+ // convert svg property name to mapshaper style equivalent
11356
+ style[styleIndex[fname]] = val;
11357
+ }
11358
+
11359
+ if (style.strokeWidth && !style.strokeColor) {
11360
+ style.strokeColor = 'black';
11361
+ }
11362
+ if (!('strokeWidth' in style) && style.strokeColor) {
11363
+ style.strokeWidth = 1;
11364
+ }
11365
+ if (style.radius > 0 && !style.strokeWidth && !style.fillColor && lyr.geometry_type == 'point') {
11366
+ style.fillColor = 'black';
11367
+ }
11368
+ };
11369
+ var style = {styler: styler, type: 'styled'};
11370
+ // use squares if radius is missing... (TODO: check behavior with labels, etc)
11371
+ if (lyr.geometry_type == 'point' && fields.includes('r') === false) {
11372
+ style.dotSize = 1;
11373
+ }
11374
+ return style;
11375
+ }
11376
+
11377
+ // check if layer should be displayed with a full style
11378
+ function layerHasDrawableStyle(lyr) {
11379
+ var fields = getStyleFields(lyr);
11380
+ if (lyr.geometry_type == 'point') {
11381
+ // return fields.indexOf('r') > -1; // require 'r' field for point symbols
11382
+ return fields.includes('fill') || fields.includes('r'); // support colored squares
11383
+ }
11384
+ return utils$1.difference(fields, ['opacity', 'class']).length > 0;
11385
+ }
11386
+
11387
+ function getStyleFields(lyr) {
11388
+ var fields = lyr.data ? lyr.data.getFields() : [];
11389
+ return internal.findStylePropertiesBySymbolGeom(fields, lyr.geometry_type);
11390
+ }
11391
+
11394
11392
  function MapExtent(_position) {
11395
11393
  var _scale = 1,
11396
11394
  _cx, _cy, // center in geographic units
@@ -12198,10 +12196,10 @@
12198
12196
  var scale = style.dotScale || 1;
12199
12197
  size += (scale - 1) / 2;
12200
12198
  size *= Math.pow(scale, 0.3);
12201
-
12202
12199
  // shrink dots slightly on retina displays, to adjust for greater clarity
12203
- // and reduce number of pixels to draw on large datasets.
12204
- return Math.round(Math.pow(GUI.getPixelRatio(), 0.8) * size);
12200
+ // and to reduce number of pixels to draw on large datasets.
12201
+ size *= Math.pow(GUI.getPixelRatio(), 0.8);
12202
+ return Math.round(size);
12205
12203
  }
12206
12204
 
12207
12205
  function getScaledTransform(ext) {
@@ -12518,14 +12516,18 @@
12518
12516
  // is noticeably slower during animations with multiple canvases.
12519
12517
  // Highlights are drawn on a separate canvas while hovering, because this
12520
12518
  // is generally faster than redrawing all of the shapes.
12521
- this.drawOverlayLayer = function(lyr, action) {
12522
- if (action == 'hover' && lyr) {
12519
+ this.drawOverlayLayers = function(layers, action) {
12520
+ var canv;
12521
+ if (action == 'hover') {
12522
+ canv = _overlayCanv;
12523
12523
  _overlayCanv.prep(_ext);
12524
- drawCanvasLayer(lyr, _overlayCanv);
12525
12524
  } else {
12525
+ canv = _mainCanv;
12526
12526
  _overlayCanv.hide();
12527
- drawCanvasLayer(lyr, _mainCanv);
12528
12527
  }
12528
+ layers.forEach(function(lyr) {
12529
+ drawCanvasLayer(lyr, canv);
12530
+ });
12529
12531
  };
12530
12532
 
12531
12533
  this.drawFurnitureLayers = function(layers, action) {
@@ -12837,14 +12839,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12837
12839
  _ext = new MapExtent(position),
12838
12840
  _visibleLayers = [], // cached visible map layers
12839
12841
  _hit, _nav,
12840
- _intersectionLyr, _activeLyr, _overlayLyr,
12842
+ _intersectionLyr, _activeLyr, _overlayLayers,
12841
12843
  _renderer, _dynamicCRS;
12842
12844
 
12843
12845
  _mouse.disable(); // wait for gui.focus() to activate mouse events
12844
12846
 
12845
12847
  model.on('select', function(e) {
12846
12848
  _intersectionLyr = null;
12847
- _overlayLyr = null;
12849
+ // _overlayLyr = null;
12848
12850
  });
12849
12851
 
12850
12852
  gui.on('active', function() {
@@ -12872,8 +12874,8 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12872
12874
  if (lyr == _intersectionLyr) return; // no change
12873
12875
  if (lyr) {
12874
12876
  enhanceLayerForDisplay(lyr, dataset, getDisplayOptions());
12877
+ lyr.gui.style = getIntersectionStyle(lyr.gui.displayLayer, getGlobalStyleOptions());
12875
12878
  _intersectionLyr = lyr;
12876
- _intersectionLyr.gui.style = getIntersectionStyle(_intersectionLyr.gui.displayLayer, getGlobalStyleOptions());
12877
12879
  } else {
12878
12880
  _intersectionLyr = null;
12879
12881
  }
@@ -12901,16 +12903,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12901
12903
  return p1 && p2 ? formatCoordsForDisplay(p1, p2) : null;
12902
12904
  };
12903
12905
 
12904
- // this.getCenterLngLat = function() {
12905
- // var bounds = _ext.getBounds();
12906
- // var crs = this.getDisplayCRS();
12907
- // // TODO: handle case where active layer is a frame layer
12908
- // if (!bounds.hasBounds() || !crs) {
12909
- // return null;
12910
- // }
12911
- // return internal.toLngLat([bounds.centerX(), bounds.centerY()], crs);
12912
- // };
12913
-
12914
12906
  this.getDisplayCRS = function() {
12915
12907
  if (!_activeLyr) {
12916
12908
  return _dynamicCRS || internal.parseCrsString('wgs84');
@@ -12970,9 +12962,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12970
12962
  projectLayerForDisplay(lyr, newCRS);
12971
12963
  });
12972
12964
 
12973
- // kludge to make sure all layers have styles
12974
- updateLayerStyles(getContentLayers());
12975
-
12976
12965
  // Update map extent (also triggers redraw)
12977
12966
  projectMapExtent(_ext, oldCRS, this.getDisplayCRS(), calcFullBounds());
12978
12967
  updateFullBounds();
@@ -12993,7 +12982,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
12993
12982
  new BoxTool(gui, _ext, _nav),
12994
12983
  new RectangleControl(gui, _hit),
12995
12984
  initInteractiveEditing(gui, _ext, _hit);
12996
- _hit.on('change', updateOverlayLayer);
12985
+ _hit.on('change', function() { drawLayers('hover'); });
12997
12986
  }
12998
12987
 
12999
12988
  _ext.on('change', function(e) {
@@ -13021,9 +13010,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13021
13010
  var prevLyr = _activeLyr || null;
13022
13011
  var fullBounds;
13023
13012
  var needReset;
13024
- if (!prevLyr) {
13025
- // initMap(); // first call
13026
- }
13027
13013
 
13028
13014
  if (arcsMayHaveChanged(e.flags)) {
13029
13015
  // regenerate filtered arcs the next time they are needed for rendering
@@ -13048,7 +13034,9 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13048
13034
 
13049
13035
  if (updated.layer) {
13050
13036
  _activeLyr = updated.layer;
13051
- initActiveLayer();
13037
+ enhanceLayerForDisplay(_activeLyr, updated.dataset, getDisplayOptions());
13038
+ // need to set layer style so hit detection can calculate size of certain symbols
13039
+ _activeLyr.gui.style = getActiveLayerStyle(_activeLyr.gui.displayLayer, getGlobalStyleOptions());
13052
13040
  } else {
13053
13041
  _activeLyr = null;
13054
13042
  }
@@ -13084,23 +13072,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13084
13072
  map.dispatchEvent('updated');
13085
13073
  }
13086
13074
 
13087
-
13088
- function updateOverlayLayer(e) {
13089
- var style = !_activeLyr?.gui?.style ? null :
13090
- getOverlayStyle(_activeLyr.gui.displayLayer, e, getGlobalStyleOptions());
13091
- if (style) {
13092
- var displayLayer = filterLayerByIds(_activeLyr.gui.displayLayer, style.ids);
13093
- var gui = Object.assign({}, _activeLyr.gui, {style, displayLayer});
13094
- style.dotScale = _activeLyr.gui.style.dotScale;
13095
- _overlayLyr = utils$1.defaults({gui}, _activeLyr);
13096
- } else {
13097
- _overlayLyr = null;
13098
- }
13099
-
13100
- // 'hover' avoids redrawing all svg symbols when only highlight needs to refresh
13101
- drawLayers('hover');
13102
- }
13103
-
13104
13075
  function getDisplayOptions() {
13105
13076
  return {
13106
13077
  crs: _dynamicCRS
@@ -13235,12 +13206,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13235
13206
  });
13236
13207
  }
13237
13208
 
13238
- function initActiveLayer() {
13239
- var active = model.getActiveLayer();
13240
- enhanceLayerForDisplay(active.layer, active.dataset, getDisplayOptions());
13241
- active.layer.gui.style = getActiveLayerStyle(active.layer.gui.displayLayer, getGlobalStyleOptions());
13242
- }
13243
-
13244
13209
  function getDrawableFurnitureLayers(layers) {
13245
13210
  if (!isPreviewView()) return [];
13246
13211
  return getVisibleMapLayers().filter(function(o) {
@@ -13323,14 +13288,25 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13323
13288
  contentLayers = contentLayers.concat(_intersectionLyr);
13324
13289
  }
13325
13290
  // moved this below intersection layer addition, so intersection dots get scaled
13326
- adjustPointSymbolSizes(contentLayers, _overlayLyr, _ext);
13291
+
13292
+ // Adjust dot size based on total visible dots TODO: move this
13293
+ var dotScale = calcDotScale(contentLayers, _ext);
13294
+ contentLayers.forEach(function(lyr) {
13295
+ lyr.gui.style.dotScale = dotScale;
13296
+ });
13327
13297
 
13328
13298
  // RENDERING
13329
13299
  // draw main content layers
13330
13300
  _renderer.drawMainLayers(contentLayers, action);
13301
+
13331
13302
  // draw hover & selection overlay
13332
- _renderer.drawOverlayLayer(_overlayLyr, action);
13333
- // draw furniture
13303
+ if (!_overlayLayers || action != 'nav') {
13304
+ // cache layers to use when panning/zooming
13305
+ _overlayLayers = getOverlayLayers(_activeLyr, _hit.getHitState(), getGlobalStyleOptions());
13306
+ }
13307
+ _renderer.drawOverlayLayers(_overlayLayers, action);
13308
+
13309
+ // TODO: draw furniture
13334
13310
  // _renderer.drawFurnitureLayers(furnitureLayers, action);
13335
13311
  gui.dispatchEvent('map_rendered');
13336
13312
  }
@@ -13567,12 +13543,14 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
13567
13543
  }
13568
13544
 
13569
13545
  function initMap() {
13546
+ var accessToken = (window.location.hostname == 'localhost' ?
13547
+ params.localhost_key : params.production_key) || params.key;
13570
13548
  if (!enabled() || map || loading) return;
13571
13549
  loading = true;
13572
13550
  loadStylesheet(params.css);
13573
13551
  loadScript(params.js, function() {
13574
13552
  map = new window.mapboxgl.Map({
13575
- accessToken: params.key,
13553
+ accessToken: accessToken,
13576
13554
  logoPosition: 'bottom-left',
13577
13555
  container: mapEl.node(),
13578
13556
  style: activeStyle.url,
package/www/mapshaper.js CHANGED
@@ -19290,7 +19290,7 @@
19290
19290
 
19291
19291
  // symType: point, polygon, polyline, label
19292
19292
  function applyStyleAttributes(svgObj, symType, rec, filter) {
19293
- var fields = findPropertiesBySymbolGeom(Object.keys(rec || {}), symType);
19293
+ var fields = findStylePropertiesBySymbolGeom(Object.keys(rec || {}), symType);
19294
19294
  for (var i=0, n=fields.length; i<n; i++) {
19295
19295
  if (filter && !filter(fields[i])) continue;
19296
19296
  setAttribute(svgObj, fields[i], rec[fields[i]]);
@@ -19318,7 +19318,7 @@
19318
19318
  return name in symbolPropertyTypes;
19319
19319
  }
19320
19320
 
19321
- function findPropertiesBySymbolGeom(fields, type) {
19321
+ function findStylePropertiesBySymbolGeom(fields, type) {
19322
19322
  var index = propertiesBySymbolType[type] || {};
19323
19323
  return fields.filter(function(name) {
19324
19324
  return name in index;
@@ -19467,7 +19467,7 @@
19467
19467
  var SvgProperties = /*#__PURE__*/Object.freeze({
19468
19468
  __proto__: null,
19469
19469
  applyStyleAttributes: applyStyleAttributes,
19470
- findPropertiesBySymbolGeom: findPropertiesBySymbolGeom,
19470
+ findStylePropertiesBySymbolGeom: findStylePropertiesBySymbolGeom,
19471
19471
  getSymbolDataAccessor: getSymbolDataAccessor,
19472
19472
  getSymbolPropertyAccessor: getSymbolPropertyAccessor,
19473
19473
  isSupportedSvgStyleProperty: isSupportedSvgStyleProperty,
@@ -46041,7 +46041,7 @@ ${svg}
46041
46041
  });
46042
46042
  }
46043
46043
 
46044
- var version = "0.6.104";
46044
+ var version = "0.6.106";
46045
46045
 
46046
46046
  // Parse command line args into commands and run them
46047
46047
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.