diff --git a/css/20_map.css b/css/20_map.css index 29fa82a7b..5cd5771ac 100644 --- a/css/20_map.css +++ b/css/20_map.css @@ -1,6 +1,6 @@ /* base styles */ .layer-osm path:not(.oneway-marker-path) { /* IE/Edge needs :not(.oneway) */ - fill: none; + fill: none; } .layer-osm path.viewfield-marker-path { /* IE/Edge rule for marker style */ fill: #333; @@ -214,7 +214,6 @@ text.pointlabel { dominant-baseline: auto; } -text.gpxlabel-halo, .layer-labels-halo text { opacity: 0.7; stroke: #fff; @@ -272,13 +271,21 @@ path.gpx { fill: none; } +text.gpxlabel-halo, +text.gpxlabel { + font-size: 10px; + font-weight: bold; + dominant-baseline: middle; +} + text.gpxlabel { fill: #ff26d4; } -text.gpxlabel-halo, -text.gpxlabel { - font-size: 12px; - font-weight: bold; - dominant-baseline: middle; -} \ No newline at end of file +text.gpxlabel-halo { + opacity: 0.7; + stroke: #000; + stroke-width: 5px; + stroke-miterlimit: 1; +} + diff --git a/modules/svg/gpx.js b/modules/svg/gpx.js index 931189aa2..e3f33601f 100644 --- a/modules/svg/gpx.js +++ b/modules/svg/gpx.js @@ -4,37 +4,36 @@ import _isUndefined from 'lodash-es/isUndefined'; import _reduce from 'lodash-es/reduce'; import _union from 'lodash-es/union'; -import { - geoBounds as d3_geoBounds, - geoPath as d3_geoPath -} from 'd3-geo'; - -import { - text as d3_text -} from 'd3-request'; - +import { geoBounds as d3_geoBounds } from 'd3-geo'; +import { text as d3_text } from 'd3-request'; import { event as d3_event, select as d3_select } from 'd3-selection'; import { geoExtent, geoPolygonIntersectsPolygon } from '../geo'; +import { svgPath } from './index'; import { utilDetect } from '../util/detect'; import toGeoJSON from '@mapbox/togeojson'; +var _initialized = false; +var _enabled = false; +var _geojson; + + export function svgGpx(projection, context, dispatch) { - var showLabels = true, - detected = utilDetect(), - layer, - src; + var _showLabels = true; + var detected = utilDetect(); + var layer; + var _src; function init() { - if (svgGpx.initialized) return; // run once + if (_initialized) return; // run once - svgGpx.geojson = {}; - svgGpx.enabled = true; + _geojson = {}; + _enabled = true; function over() { d3_event.stopPropagation(); @@ -54,15 +53,15 @@ export function svgGpx(projection, context, dispatch) { .on('dragexit.localgpx', over) .on('dragover.localgpx', over); - svgGpx.initialized = true; + _initialized = true; } + function drawGpx(selection) { - var geojson = svgGpx.geojson, - enabled = svgGpx.enabled; + var getPath = svgPath(projection).geojson; layer = selection.selectAll('.layer-gpx') - .data(enabled ? [0] : []); + .data(_enabled ? [0] : []); layer.exit() .remove(); @@ -75,7 +74,7 @@ export function svgGpx(projection, context, dispatch) { var paths = layer .selectAll('path') - .data([geojson]); + .data([_geojson]); paths.exit() .remove(); @@ -85,47 +84,43 @@ export function svgGpx(projection, context, dispatch) { .attr('class', 'gpx') .merge(paths); - - var path = d3_geoPath(projection); - paths - .attr('d', path); + .attr('d', getPath); - function createLabels(layer, textClass, data) { - var labels = layer.selectAll('text.' + textClass) + var labelData = _showLabels && _geojson.features ? _geojson.features : []; + labelData = labelData.filter(getPath); + + layer + .call(drawLabels, 'gpxlabel-halo', labelData) + .call(drawLabels, 'gpxlabel', labelData); + + + function drawLabels(selection, textClass, data) { + var labels = selection.selectAll('text.' + textClass) .data(data); - + + // exit labels.exit() .remove(); - + + // enter/update labels = labels.enter() .append('text') .attr('class', textClass) - .merge(labels); - - return labels; + .merge(labels) + .text(function(d) { + return d.properties.desc || d.properties.name; + }) + .attr('x', function(d) { + var centroid = getPath.centroid(d); + return centroid[0] + 11; + }) + .attr('y', function(d) { + var centroid = getPath.centroid(d); + return centroid[1]; + }); } - - var labelsData = showLabels && geojson.features ? geojson.features : []; - createLabels(layer, 'gpxlabel-halo', labelsData); - createLabels(layer, 'gpxlabel', labelsData); - - var labels = layer.selectAll('text'); - - labels - .text(function(d) { - return d.properties.desc || d.properties.name; - }) - .attr('x', function(d) { - var centroid = path.centroid(d); - return centroid[0] + 11; - }) - .attr('y', function(d) { - var centroid = path.centroid(d); - return centroid[1]; - }); - } @@ -165,30 +160,29 @@ export function svgGpx(projection, context, dispatch) { drawGpx.showLabels = function(_) { - if (!arguments.length) return showLabels; - showLabels = _; + if (!arguments.length) return _showLabels; + _showLabels = _; return this; }; drawGpx.enabled = function(_) { - if (!arguments.length) return svgGpx.enabled; - svgGpx.enabled = _; + if (!arguments.length) return _enabled; + _enabled = _; dispatch.call('change'); return this; }; drawGpx.hasGpx = function() { - var geojson = svgGpx.geojson; - return (!(_isEmpty(geojson) || _isEmpty(geojson.features))); + return (!(_isEmpty(_geojson) || _isEmpty(_geojson.features))); }; drawGpx.geojson = function(gj) { - if (!arguments.length) return svgGpx.geojson; + if (!arguments.length) return _geojson; if (_isEmpty(gj) || _isEmpty(gj.features)) return this; - svgGpx.geojson = gj; + _geojson = gj; dispatch.call('change'); return this; }; @@ -197,8 +191,7 @@ export function svgGpx(projection, context, dispatch) { drawGpx.url = function(url) { d3_text(url, function(err, data) { if (!err) { - src = url; - + _src = url; var extension = getExtension(url); parseSaveAndZoom(extension, data); } @@ -213,10 +206,8 @@ export function svgGpx(projection, context, dispatch) { reader = new FileReader(); reader.onload = (function(file) { - src = file.name; - + _src = file.name; var extension = getExtension(file.name); - return function (e) { parseSaveAndZoom(extension, e.target.result); }; @@ -226,38 +217,39 @@ export function svgGpx(projection, context, dispatch) { return this; }; + drawGpx.getSrc = function () { - return src; + return _src; }; + drawGpx.fitZoom = function() { if (!this.hasGpx()) return this; - var geojson = svgGpx.geojson; - var map = context.map(), - viewport = map.trimmedExtent().polygon(), - coords = _reduce(geojson.features, function(coords, feature) { - var c = feature.geometry.coordinates; + var map = context.map(); + var viewport = map.trimmedExtent().polygon(); + var coords = _reduce(_geojson.features, function(coords, feature) { + var c = feature.geometry.coordinates; - /* eslint-disable no-fallthrough */ - switch (feature.geometry.type) { - case 'Point': - c = [c]; - case 'MultiPoint': - case 'LineString': - break; + /* eslint-disable no-fallthrough */ + switch (feature.geometry.type) { + case 'Point': + c = [c]; + case 'MultiPoint': + case 'LineString': + break; - case 'MultiPolygon': - c = _flatten(c); - case 'Polygon': - case 'MultiLineString': - c = _flatten(c); - break; - } - /* eslint-enable no-fallthrough */ + case 'MultiPolygon': + c = _flatten(c); + case 'Polygon': + case 'MultiLineString': + c = _flatten(c); + break; + } + /* eslint-enable no-fallthrough */ - return _union(coords, c); - }, []); + return _union(coords, c); + }, []); if (!geoPolygonIntersectsPolygon(viewport, coords, true)) { var extent = geoExtent(d3_geoBounds({ type: 'LineString', coordinates: coords }));