Skip to content

Instantly share code, notes, and snippets.

@mapsense-examples
Last active August 29, 2015 14:26

Revisions

  1. @jhnklly jhnklly revised this gist Aug 26, 2015. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -379,7 +379,11 @@
    return function(t) {
    var p = path.getPointAtLength(t * l);

    // This works for Chrome & Safari, but getCTM is different in Firefox
    var m = document.querySelector('.route').getCTM();

    //var begin = document.querySelectorAll('.endpoint')[0];
    //var m = begin.getCTM();
    // matrix(1.3203125,0,0,1.3203125,510,256)
    //transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    var scale_x = m.a,
    @@ -391,8 +395,8 @@

    console.log(p.y, scale_y, move_y);

    move_x = parseInt(scale_x * p.x + move_x);
    move_y = parseInt(scale_y * p.y + move_y);
    move_x = scale_x * p.x + move_x;
    move_y = scale_y * p.y + move_y;


    var transformer = "matrix("+scale_x+","+skew_1+","+skew_2+","+ scale_y+","+move_x+","+move_y+")";
  2. @jhnklly jhnklly revised this gist Aug 26, 2015. 2 changed files with 28 additions and 11 deletions.
    37 changes: 28 additions & 9 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -147,11 +147,7 @@
    then add 1.
    black = transparent; white = opaque
    -->
    <feColorMatrix in="r2" type="matrix" values="
    0 0 0 0 0.58
    0 0 0 0 0.36
    0 0 0 0 0.106
    0 0 0 -1 1" result="r3"></feColorMatrix>
    <feColorMatrix in="r2" type="matrix" values="0 0 0 0 0.58 0 0 0 0 0.36 0 0 0 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>

    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>

    @@ -367,7 +363,14 @@

    marker.transition()
    .duration(9000)
    .attrTween("transform", translateAlong(path.node()));
    .attrTween("transform", translateAlong(path.node()))
    //.attrTween("-moz-transform", translateAlong(path.node()));

    map.on('move', function(){
    var marker = d3.select("#moving_marker");
    var end = document.querySelectorAll('.endpoint')[1];
    followTheLeader(marker,end);
    })
    }

    function translateAlong(path) {
    @@ -376,10 +379,26 @@
    return function(t) {
    var p = path.getPointAtLength(t * l);

    var m = document.querySelector('.route').getCTM(),
    transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    transformer += " translate(" + p.x + "," + p.y + ")";
    var m = document.querySelector('.route').getCTM();
    // matrix(1.3203125,0,0,1.3203125,510,256)
    //transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    var scale_x = m.a,
    skew_1 = m.b,
    skew_2 = m.c,
    scale_y = m.d,
    move_x = m.e,
    move_y = m.f;

    console.log(p.y, scale_y, move_y);

    move_x = parseInt(scale_x * p.x + move_x);
    move_y = parseInt(scale_y * p.y + move_y);


    var transformer = "matrix("+scale_x+","+skew_1+","+skew_2+","+ scale_y+","+move_x+","+move_y+")";
    //transformer += " translate(" + p.x + "," + p.y + ")";

    //console.log( transformer);
    return transformer;
    };
    };
    2 changes: 0 additions & 2 deletions simple.css
    Original file line number Diff line number Diff line change
    @@ -10,8 +10,6 @@
    }
    .mapsense-simple.tile-background {
    fill: #CBE6F3;
    //fill: RGBA(203, 230, 243, 0.5);
    //fill: none;
    }
    .mapsense-simple.land {
    fill: #ffffff;
  3. @jhnklly jhnklly revised this gist Aug 26, 2015. 1 changed file with 9 additions and 76 deletions.
    85 changes: 9 additions & 76 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -320,21 +320,9 @@
    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.4);

    // Run the marker animation
    marauderFn();

    /*var marker = d3.select("#moving_marker");
    var path = d3.select(".route");
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];
    d3.select('#moving_marker')
    .data(G.route_coordinates)
    .transition()
    .duration(9000) // the whole transition, not each step
    //.attrTween("transform", translateFn());
    .attrTween("transform", translateAlong(path.node()))
    .each("end", transition);*/

    });


    @@ -373,72 +361,20 @@
    return transformer;
    };

    // The function that actually does the moving:
    function translateFn() {
    // We only use 'd', but list d,i,a as params just to show can have them as params.
    // Code only really uses d and t.
    return function(d, i, a) {
    return function(t) {
    // t is the fraction of time (between 0 and 1)
    // since the transition began.

    var index_int = parseInt(100*t-1);
    var marker = d3.select("#moving_marker");
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];

    if (t==1) {
    // When done, bind the marker to the end location
    map.on('move', function(){
    var end = document.querySelectorAll('.endpoint')[1];
    followTheLeader(marker,end);
    })
    return followTheLeader(marker,end);
    } else if (index_int==0) {
    var point = map.locationPoint({ lon: G.route_coordinates[0][0], lat: G.route_coordinates[0][1] });

    var new_x = point.x;
    var new_y = point.y;
    var translation = "translate(" + new_x + "," + new_y + ")";
    //console.log(translation);
    //return translation;
    return followTheLeader(marker,begin);
    } else if (index_int < G.route_coordinates.length) {
    var p = d3.select('.route').node();
    var len = p.getTotalLength();
    G.moving_point = p.getPointAtLength(t * len);

    var m = begin.getCTM();
    var transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";

    //Move the marker to that point
    //marker.attr("transform", translation);
    return transformer;
    }
    };
    };
    }


    function marauderFn() {
    var marker = d3.select("#moving_marker");
    var path = d3.select(".route");
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];

    marker.transition()
    .duration(9000)
    .attrTween("transform", translateAlong(path.node()))
    //.each("end", marauderFn);
    var marker = d3.select("#moving_marker");
    var path = d3.select(".route");

    marker.transition()
    .duration(9000)
    .attrTween("transform", translateAlong(path.node()));
    }

    // Returns an attrTween for translating along the specified path element.
    function translateAlong(path) {
    var l = path.getTotalLength();
    return function(d, i, a) {
    return function(t) {
    var p = path.getPointAtLength(t * l);
    //return "translate(" + p.x + "," + p.y + ")";

    var m = document.querySelector('.route').getCTM(),
    transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    @@ -460,9 +396,8 @@
    }


    function twoCoords2geojsonArc(coord_a, coord_b) { // [lon, lat], [lon, lat]
    // --- Add paths
    // Format of object is an array of objects, each containing
    function twoCoords2geojsonArc(coord_a, coord_b) {
    // [lon, lat], [lon, lat]

    var features = [];
    var geojson = { 'type': 'FeatureCollection',
    @@ -482,9 +417,7 @@
    var gj_line = line.json();
    features.push(line.json());


    return geojson;
    //console.log(JSON.stringify(geojson));
    }


  4. @jhnklly jhnklly revised this gist Aug 26, 2015. 1 changed file with 163 additions and 142 deletions.
    305 changes: 163 additions & 142 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -38,6 +38,7 @@
    stroke-width: 2;
    stroke-dasharray: 5,6;
    stroke-linejoin: round;
    filter: url(#filter_handdrawn);
    }

    .graticule { stroke: RGBA(153, 180, 193, 1);; }
    @@ -56,6 +57,9 @@

    .oldfont { font: bold 30px Stalemate; }

    path {
    }

    #compass {
    background-image: url(compass_jmk.svg), none;
    background-repeat: no-repeat;
    @@ -87,54 +91,87 @@
    fill: RGBA(203, 230, 243, 0.75);
    }

    .foobar { fill: rgba(0,0,128,0.5); stroke: green; }

    </style>
    </head>

    <body>

    <div id="myMap"></div>
    <div id="pane"></div>
    <!--
    <div id="test"></div>
    <div id="seadragon"></div>
    -->
    <div id="wind"></div>
    <div id="compass"></div>

    <svg>
    <defs id="the_defs">
    <filter id="gblur">
    <filter id="filter_gblur">
    <!-- outer glow (blue) -->
    <!-- http://www.svgbasics.com/filters4.html
    r g b a offset
    -->
    <!--
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    -->

    <!-- feMorphology: erode or dilate (make fatter or thinner; good for alpha channel) -->


    <feMorphology in="SourceGraphic" radius="1" operator="dilate" result="mask"></feMorphology>

    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 1 0" result="r0"></feColorMatrix>

    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>

    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">

    <feMerge result="outer_glow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>


    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <!-- Use feColorMatrix to make a copy that's black but with 100% transparency: -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <!-- "Erode" it by radius; meaning shrink inward.
    So radius is the width of the tinted band -->
    <feMorphology in="mask" radius="2" operator="erode" result="r1"></feMorphology>
    <!-- blur it! Unnecessary if you want solid band -->
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>

    <!-- Set the color of the tint via the o values.
    For the opacity filter:
    first invert it (),
    then add 1.
    black = transparent; white = opaque
    -->
    <feColorMatrix in="r2" type="matrix" values="
    0 0 0 0 0.58
    0 0 0 0 0.36
    0 0 0 0 0.106
    0 0 0 -1 1" result="r3"></feColorMatrix>

    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">

    <feMerge result="inner_glow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    <!--
    <feMergeNode in="outer_glow"></feMergeNode>
    -->
    <feMergeNode in="inner_glow"></feMergeNode>
    </feMerge>
    </filter>

    <pattern id="dragon_pattern" x="0" y="0" patternUnits="userSpaceOnUse" height="100" width="100">
    <image x="50" y="50" height="100" width="100"xlink:href="seadragon2.png"></image>
    </pattern>
    <filter id="filter_handdrawn" color-interpolation-filters="sRGB">
    <feTurbulence result="turb" baseFrequency="0.04" type="turbulence" seed="0" numOctaves="3" id="feTurbulence5437" />
    <feDisplacementMap in2="turb" scale="6.6" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" id="feDisplacementMap5439" />
    </filter>

    </defs>
    </svg>
    @@ -183,6 +220,8 @@
    ;
    return classes.join(" ");
    }
    } else {
    s.attr('filter', 'url(#filter_handdrawn)')
    }
    if (feature.properties.sub_layer)
    classes.push(feature.properties.sub_layer);
    @@ -191,9 +230,10 @@
    });

    d3.selectAll('.fadeland')
    .attr('filter','url(#gblur)')
    .attr('filter','url(#filter_gblur)')
    .attr('class','')
    .attr('stroke','rgba(68, 167, 228, 1)')
    //.attr('stroke','rgba(255, 0, 0, 1)')
    .attr('fill','#F5F0ED')
    .attr('stroke-width','1')
    .attr('paint-order', 'stroke')
    @@ -226,11 +266,9 @@
    })
    ;

    return "point";
    return "endpoint";
    });



    })
    .scale("fixed");

    @@ -270,7 +308,7 @@
    //grp.append("image")
    d3.select('.mapsense-map').append("image")
    .attr("xlink:href", "bike.png")
    .attr("id","moving_marker")
    .attr("id","moving_marker")
    .attr("x", "-10")
    .attr("y", "-25")
    .attr("width", "30")
    @@ -282,153 +320,136 @@
    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.4);

    d3.select('#moving_marker')
    .data(G.route_coordinates)
    //d3.select(this)
    .transition()
    .duration(9000) // the whole transition, not each step
    //.delay(1000)
    .attrTween("transform", translateFn());
    marauderFn();

    /*var marker = d3.select("#moving_marker");
    var path = d3.select(".route");
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];
    d3.select('#moving_marker')
    .data(G.route_coordinates)
    .transition()
    .duration(9000) // the whole transition, not each step
    //.attrTween("transform", translateFn());
    .attrTween("transform", translateAlong(path.node()))
    .each("end", transition);*/

    });


    // Thar be dragons
    G.seadragon = mapsense.geoJson()
    .features([markLatLon(36.5, -73)])
    .selection(function(s){
    s.attr("class", 'sd');
    d3.select(s.node().parentNode).append("image")
    .attr("xlink:href", "seadragon2.png")
    .attr("transform",s.attr("transform"))
    .attr("x", "-50")
    .attr("y", "-50")
    .attr("width", "100")
    .attr("height", "100");

    s.attr("r", "50");
    })
    .scale("fixed");

    map.add(G.seadragon);


    // Update the attribution
    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>HatTip <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);

    });


    function followTheLeader(follower, leader) {
    var m = leader.getCTM(),
    transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    follower.attr('transform', transformer);
    return transformer;
    };

    // The function that actually does the moving:
    function translateFn() {

    // We only use 'd', but list d,i,a as params just to show can have them as params.
    // Code only really uses d and t.
    return function(d, i, a) {
    return function(t) {

    // 't': what's t? T is the fraction of time (between 0 and 1) since the
    // transition began. Handy.
    // t is the fraction of time (between 0 and 1)
    // since the transition began.

    var index_int = parseInt(100*t-1);

    var marker = d3.select("#moving_marker");

    var screen_xy = map.locationPoint({ lon: G.route_coordinates[index_int][0], lat: G.route_coordinates[index_int][1] });

    var new_x = screen_xy.x; // - 15;
    var new_y = screen_xy.y; // - 27;
    var translation = "translate(" + new_x + "," + new_y + ")";
    //var translation = "translate(" + 50 + "," + 80 + ")";

    //Move the marker to that point
    marker.attr("transform", translation); //move marker


    return translation;
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];

    if (t==1) {
    // When done, bind the marker to the end location
    map.on('move', function(){
    var end = document.querySelectorAll('.endpoint')[1];
    followTheLeader(marker,end);
    })
    return followTheLeader(marker,end);
    } else if (index_int==0) {
    var point = map.locationPoint({ lon: G.route_coordinates[0][0], lat: G.route_coordinates[0][1] });

    var new_x = point.x;
    var new_y = point.y;
    var translation = "translate(" + new_x + "," + new_y + ")";
    //console.log(translation);
    //return translation;
    return followTheLeader(marker,begin);
    } else if (index_int < G.route_coordinates.length) {
    var p = d3.select('.route').node();
    var len = p.getTotalLength();
    G.moving_point = p.getPointAtLength(t * len);

    var m = begin.getCTM();
    var transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";

    //Move the marker to that point
    //marker.attr("transform", translation);
    return transformer;
    }
    };
    };
    }


    function marauderFn() {
    var marker = d3.select("#moving_marker");
    var path = d3.select(".route");
    var begin = document.querySelectorAll('.endpoint')[0];
    var end = document.querySelectorAll('.endpoint')[1];

    // Route is from https://www.raceacrossamerica.org/raam
    /* d3.json('raamdens.geojson', function(data) {
    G.route = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "route");
    })
    ;
    map.add(G.route);
    G.route_coordinates = data.features[0].geometry.coordinates;
    // HatTip! https://www.mapbox.com/mapbox.js/example/v1.0.0/animate-marker-along-line/
    G.j = 0;
    G.point = markLatLon(0,0); // placeholder; we'll update with route coordinates
    G.pt_layer = mapsense.geoJson()
    .scale("fixed")
    .features([G.point])
    .selection(function(s){
    s.attr('class','marker');
    s.attr("r", "15");
    var grp = d3.select(s.node().parentNode).append("g")
    .attr("width","30")
    .attr("height","30")
    .attr("transform",s.attr("transform"));
    grp.append("image")
    .attr("xlink:href", "bike.png")
    .attr("x", "-10")
    .attr("y", "-25")
    .attr("width", "30")
    .attr("height", "30");
    });
    map.add(G.pt_layer);
    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.4);
    // Start the recursive move function
    updatePosition();
    });
    */

    // Thar be dragons
    G.seadragon = mapsense.geoJson()
    .features([markLatLon(36.5, -73)])
    .selection(function(s){
    s.attr("class", 'sd');
    d3.select(s.node().parentNode).append("image")
    .attr("xlink:href", "seadragon2.png")
    .attr("transform",s.attr("transform"))
    .attr("x", "-50")
    .attr("y", "-50")
    .attr("width", "100")
    .attr("height", "100");

    s.attr("r", "50");
    })
    .scale("fixed");

    map.add(G.seadragon);


    // Update the attribution
    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>HatTip <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);

    });

    marker.transition()
    .duration(9000)
    .attrTween("transform", translateAlong(path.node()))
    //.each("end", marauderFn);
    }

    function updatePosition() {
    // Put the marker at the line's first coordinate
    /*G.point.geometry.coordinates[0] = G.route_coordinates[G.j][0];
    G.point.geometry.coordinates[1] = G.route_coordinates[G.j][1];
    G.pt_layer.features([G.point]);
    */
    // Smoother? Don't geojson the marker, just put the image at screen xy of
    // each route coord. Then can animate/transition?
    var screen_xy = map.locationPoint({ lon: G.route_coordinates[G.j][0], lat: G.route_coordinates[G.j][1] });
    // Returns an attrTween for translating along the specified path element.
    function translateAlong(path) {
    var l = path.getTotalLength();
    return function(d, i, a) {
    return function(t) {
    var p = path.getPointAtLength(t * l);
    //return "translate(" + p.x + "," + p.y + ")";

    var new_x = screen_xy.x - 15;
    var new_y = screen_xy.y - 27;
    var m = document.querySelector('.route').getCTM(),
    transformer = "matrix("+m.a+","+m.b+","+m.c+","+ m.d+","+m.e+","+m.f+")";
    transformer += " translate(" + p.x + "," + p.y + ")";

    d3.select('#moving_marker')
    //.transition('0.2s')
    .transition()
    .attr('x', new_x)
    //.transition()
    .attr('y', new_y)
    ;

    // Move to the next point of the line
    // until `j` reaches the length of the array.
    if (++G.j < G.route_coordinates.length) setTimeout(updatePosition, 50);
    return transformer;
    };
    };
    }



    function markLatLon(lat,lon,name){
    name = name || "";
    var feature = {
  5. @jhnklly jhnklly revised this gist Aug 19, 2015. 1 changed file with 261 additions and 0 deletions.
    261 changes: 261 additions & 0 deletions arc.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,261 @@
    'use strict';

    var D2R = Math.PI / 180;
    var R2D = 180 / Math.PI;

    var Coord = function(lon,lat) {
    this.lon = lon;
    this.lat = lat;
    this.x = D2R * lon;
    this.y = D2R * lat;
    };

    Coord.prototype.view = function() {
    return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
    };

    Coord.prototype.antipode = function() {
    var anti_lat = -1 * this.lat;
    var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
    return new Coord(anti_lon, anti_lat);
    };

    var LineString = function() {
    this.coords = [];
    this.length = 0;
    };

    LineString.prototype.move_to = function(coord) {
    this.length++;
    this.coords.push(coord);
    };

    var Arc = function(properties) {
    this.properties = properties || {};
    this.geometries = [];
    };

    Arc.prototype.json = function() {
    if (this.geometries.length <= 0) {
    return {'geometry': { 'type': 'LineString', 'coordinates': null },
    'type': 'Feature', 'properties': this.properties
    };
    } else if (this.geometries.length == 1) {
    return {'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords },
    'type': 'Feature', 'properties': this.properties
    };
    } else {
    var multiline = [];
    for (var i = 0; i < this.geometries.length; i++) {
    multiline.push(this.geometries[i].coords);
    }
    return {'geometry': { 'type': 'MultiLineString', 'coordinates': multiline },
    'type': 'Feature', 'properties': this.properties
    };
    }
    };

    // TODO - output proper multilinestring
    Arc.prototype.wkt = function() {
    var wkt_string = '';
    var wkt = 'LINESTRING(';
    var collect = function(c) { wkt += c[0] + ' ' + c[1] + ','; };
    for (var i = 0; i < this.geometries.length; i++) {
    if (this.geometries[i].coords.length === 0) {
    return 'LINESTRING(empty)';
    } else {
    var coords = this.geometries[i].coords;
    coords.forEach(collect);
    wkt_string += wkt.substring(0, wkt.length - 1) + ')';
    }
    }
    return wkt_string;
    };

    /*
    * http://en.wikipedia.org/wiki/Great-circle_distance
    *
    */
    var GreatCircle = function(start,end,properties) {
    if (!start || start.x === undefined || start.y === undefined) {
    throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
    }
    if (!end || end.x === undefined || end.y === undefined) {
    throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
    }
    this.start = new Coord(start.x,start.y);
    this.end = new Coord(end.x,end.y);
    this.properties = properties || {};

    var w = this.start.x - this.end.x;
    var h = this.start.y - this.end.y;
    var z = Math.pow(Math.sin(h / 2.0), 2) +
    Math.cos(this.start.y) *
    Math.cos(this.end.y) *
    Math.pow(Math.sin(w / 2.0), 2);
    this.g = 2.0 * Math.asin(Math.sqrt(z));

    if (this.g == Math.PI) {
    throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
    } else if (isNaN(this.g)) {
    throw new Error('could not calculate great circle between ' + start + ' and ' + end);
    }
    };

    /*
    * http://williams.best.vwh.net/avform.htm#Intermediate
    */
    GreatCircle.prototype.interpolate = function(f) {
    var A = Math.sin((1 - f) * this.g) / Math.sin(this.g);
    var B = Math.sin(f * this.g) / Math.sin(this.g);
    var x = A * Math.cos(this.start.y) * Math.cos(this.start.x) + B * Math.cos(this.end.y) * Math.cos(this.end.x);
    var y = A * Math.cos(this.start.y) * Math.sin(this.start.x) + B * Math.cos(this.end.y) * Math.sin(this.end.x);
    var z = A * Math.sin(this.start.y) + B * Math.sin(this.end.y);
    var lat = R2D * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
    var lon = R2D * Math.atan2(y, x);
    return [lon, lat];
    };



    /*
    * Generate points along the great circle
    */
    GreatCircle.prototype.Arc = function(npoints,options) {
    var first_pass = [];
    if (!npoints || npoints <= 2) {
    first_pass.push([this.start.lon, this.start.lat]);
    first_pass.push([this.end.lon, this.end.lat]);
    } else {
    var delta = 1.0 / (npoints - 1);
    for (var i = 0; i < npoints; ++i) {
    var step = delta * i;
    var pair = this.interpolate(step);
    first_pass.push(pair);
    }
    }
    /* partial port of dateline handling from:
    gdal/ogr/ogrgeometryfactory.cpp
    TODO - does not handle all wrapping scenarios yet
    */
    var bHasBigDiff = false;
    var dfMaxSmallDiffLong = 0;
    // from http://www.gdal.org/ogr2ogr.html
    // -datelineoffset:
    // (starting with GDAL 1.10) offset from dateline in degrees (default long. = +/- 10deg, geometries within 170deg to -170deg will be splited)
    var dfDateLineOffset = options && options.offset ? options.offset : 10;
    var dfLeftBorderX = 180 - dfDateLineOffset;
    var dfRightBorderX = -180 + dfDateLineOffset;
    var dfDiffSpace = 360 - dfDateLineOffset;

    // https://github.com/OSGeo/gdal/blob/7bfb9c452a59aac958bff0c8386b891edf8154ca/gdal/ogr/ogrgeometryfactory.cpp#L2342
    for (var j = 1; j < first_pass.length; ++j) {
    var dfPrevX = first_pass[j-1][0];
    var dfX = first_pass[j][0];
    var dfDiffLong = Math.abs(dfX - dfPrevX);
    if (dfDiffLong > dfDiffSpace &&
    ((dfX > dfLeftBorderX && dfPrevX < dfRightBorderX) || (dfPrevX > dfLeftBorderX && dfX < dfRightBorderX))) {
    bHasBigDiff = true;
    } else if (dfDiffLong > dfMaxSmallDiffLong) {
    dfMaxSmallDiffLong = dfDiffLong;
    }
    }

    var poMulti = [];
    if (bHasBigDiff && dfMaxSmallDiffLong < dfDateLineOffset) {
    var poNewLS = [];
    poMulti.push(poNewLS);
    for (var k = 0; k < first_pass.length; ++k) {
    var dfX0 = parseFloat(first_pass[k][0]);
    if (k > 0 && Math.abs(dfX0 - first_pass[k-1][0]) > dfDiffSpace) {
    var dfX1 = parseFloat(first_pass[k-1][0]);
    var dfY1 = parseFloat(first_pass[k-1][1]);
    var dfX2 = parseFloat(first_pass[k][0]);
    var dfY2 = parseFloat(first_pass[k][1]);
    if (dfX1 > -180 && dfX1 < dfRightBorderX && dfX2 == 180 &&
    k+1 < first_pass.length &&
    first_pass[k-1][0] > -180 && first_pass[k-1][0] < dfRightBorderX)
    {
    poNewLS.push([-180, first_pass[k][1]]);
    k++;
    poNewLS.push([first_pass[k][0], first_pass[k][1]]);
    continue;
    } else if (dfX1 > dfLeftBorderX && dfX1 < 180 && dfX2 == -180 &&
    k+1 < first_pass.length &&
    first_pass[k-1][0] > dfLeftBorderX && first_pass[k-1][0] < 180)
    {
    poNewLS.push([180, first_pass[k][1]]);
    k++;
    poNewLS.push([first_pass[k][0], first_pass[k][1]]);
    continue;
    }

    if (dfX1 < dfRightBorderX && dfX2 > dfLeftBorderX)
    {
    // swap dfX1, dfX2
    var tmpX = dfX1;
    dfX1 = dfX2;
    dfX2 = tmpX;
    // swap dfY1, dfY2
    var tmpY = dfY1;
    dfY1 = dfY2;
    dfY2 = tmpY;
    }
    if (dfX1 > dfLeftBorderX && dfX2 < dfRightBorderX) {
    dfX2 += 360;
    }

    if (dfX1 <= 180 && dfX2 >= 180 && dfX1 < dfX2)
    {
    var dfRatio = (180 - dfX1) / (dfX2 - dfX1);
    var dfY = dfRatio * dfY2 + (1 - dfRatio) * dfY1;
    poNewLS.push([first_pass[k-1][0] > dfLeftBorderX ? 180 : -180, dfY]);
    poNewLS = [];
    poNewLS.push([first_pass[k-1][0] > dfLeftBorderX ? -180 : 180, dfY]);
    poMulti.push(poNewLS);
    }
    else
    {
    poNewLS = [];
    poMulti.push(poNewLS);
    }
    poNewLS.push([dfX0, first_pass[k][1]]);
    } else {
    poNewLS.push([first_pass[k][0], first_pass[k][1]]);
    }
    }
    } else {
    // add normally
    var poNewLS0 = [];
    poMulti.push(poNewLS0);
    for (var l = 0; l < first_pass.length; ++l) {
    poNewLS0.push([first_pass[l][0],first_pass[l][1]]);
    }
    }

    var arc = new Arc(this.properties);
    for (var m = 0; m < poMulti.length; ++m) {
    var line = new LineString();
    arc.geometries.push(line);
    var points = poMulti[m];
    for (var j0 = 0; j0 < points.length; ++j0) {
    line.move_to(points[j0]);
    }
    }
    return arc;
    };

    if (typeof window === 'undefined') {
    // nodejs
    module.exports.Coord = Coord;
    module.exports.Arc = Arc;
    module.exports.GreatCircle = GreatCircle;

    } else {
    // browser
    var arc = {};
    arc.Coord = Coord;
    arc.Arc = Arc;
    arc.GreatCircle = GreatCircle;
    }
  6. @jhnklly jhnklly revised this gist Aug 19, 2015. 1 changed file with 136 additions and 3 deletions.
    139 changes: 136 additions & 3 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,7 @@
    <script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script>
    <script src="https://developer.mapsense.co/mapsense.js" charset="utf-8"></script>
    <script src="bounds.js" charset="utf-8"></script>
    <script src="arc.js" charset="utf-8"></script>

    <link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/>
    <link type="text/css" href="simple.css" rel="stylesheet"/>
    @@ -234,11 +235,100 @@
    .scale("fixed");

    map.add(G.start_finish);

    var coord_a = G.start_finish.features()[0].geometry.coordinates;
    var coord_b = G.start_finish.features()[1].geometry.coordinates;

    G.great_arc_geojson = twoCoords2geojsonArc(coord_a, coord_b);

    G.route = mapsense.geoJson()
    .features(G.great_arc_geojson.features)
    .selection(function(d){
    d.attr("class", "route");
    })
    ;
    map.add(G.route);

    G.route_coordinates = G.great_arc_geojson.features[0].geometry.coordinates;

    // HatTip! https://www.mapbox.com/mapbox.js/example/v1.0.0/animate-marker-along-line/
    G.j = 0;
    G.point = markLatLon(0,0); // placeholder; we'll update with route coordinates

    G.pt_layer = mapsense.geoJson()
    .scale("fixed")
    .features([G.point])
    .selection(function(s){
    s.attr('class','marker');
    s.attr("r", "15");

    var grp = d3.select(s.node().parentNode).append("g")
    .attr("width","30")
    .attr("height","30")
    .attr("transform",s.attr("transform"));

    //grp.append("image")
    d3.select('.mapsense-map').append("image")
    .attr("xlink:href", "bike.png")
    .attr("id","moving_marker")
    .attr("x", "-10")
    .attr("y", "-25")
    .attr("width", "30")
    .attr("height", "30");
    });

    map.add(G.pt_layer);

    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.4);

    d3.select('#moving_marker')
    .data(G.route_coordinates)
    //d3.select(this)
    .transition()
    .duration(9000) // the whole transition, not each step
    //.delay(1000)
    .attrTween("transform", translateFn());

    });



    // The function that actually does the moving:
    function translateFn() {

    // We only use 'd', but list d,i,a as params just to show can have them as params.
    // Code only really uses d and t.
    return function(d, i, a) {
    return function(t) {

    // 't': what's t? T is the fraction of time (between 0 and 1) since the
    // transition began. Handy.

    var index_int = parseInt(100*t-1);

    var marker = d3.select("#moving_marker");

    var screen_xy = map.locationPoint({ lon: G.route_coordinates[index_int][0], lat: G.route_coordinates[index_int][1] });

    var new_x = screen_xy.x; // - 15;
    var new_y = screen_xy.y; // - 27;
    var translation = "translate(" + new_x + "," + new_y + ")";
    //var translation = "translate(" + 50 + "," + 80 + ")";

    //Move the marker to that point
    marker.attr("transform", translation); //move marker


    return translation;
    };
    };
    }



    // Route is from https://www.raceacrossamerica.org/raam
    d3.json('raamdens.geojson', function(data) {
    /* d3.json('raamdens.geojson', function(data) {
    G.route = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    @@ -281,7 +371,7 @@
    // Start the recursive move function
    updatePosition();
    });

    */

    // Thar be dragons
    G.seadragon = mapsense.geoJson()
    @@ -313,9 +403,24 @@

    function updatePosition() {
    // Put the marker at the line's first coordinate
    G.point.geometry.coordinates[0] = G.route_coordinates[G.j][0];
    /*G.point.geometry.coordinates[0] = G.route_coordinates[G.j][0];
    G.point.geometry.coordinates[1] = G.route_coordinates[G.j][1];
    G.pt_layer.features([G.point]);
    */
    // Smoother? Don't geojson the marker, just put the image at screen xy of
    // each route coord. Then can animate/transition?
    var screen_xy = map.locationPoint({ lon: G.route_coordinates[G.j][0], lat: G.route_coordinates[G.j][1] });

    var new_x = screen_xy.x - 15;
    var new_y = screen_xy.y - 27;

    d3.select('#moving_marker')
    //.transition('0.2s')
    .transition()
    .attr('x', new_x)
    //.transition()
    .attr('y', new_y)
    ;

    // Move to the next point of the line
    // until `j` reaches the length of the array.
    @@ -334,5 +439,33 @@
    }


    function twoCoords2geojsonArc(coord_a, coord_b) { // [lon, lat], [lon, lat]
    // --- Add paths
    // Format of object is an array of objects, each containing

    var features = [];
    var geojson = { 'type': 'FeatureCollection',
    'features': features
    };

    var start = {
    x: coord_a[0],
    y: coord_a[1]
    };
    var end = {
    x: coord_b[0],
    y: coord_b[1]
    }
    var generator = new arc.GreatCircle(start, end, {'name': ''});
    var line = generator.Arc(100,{offset:10}); // lines w/in 10deg of dateline will be split
    var gj_line = line.json();
    features.push(line.json());


    return geojson;
    //console.log(JSON.stringify(geojson));
    }


    </script>
    </html>
  7. @jhnklly jhnklly revised this gist Aug 19, 2015. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -59,8 +59,8 @@
    background-image: url(compass_jmk.svg), none;
    background-repeat: no-repeat;
    position: absolute;
    bottom: 30px;
    left: 30px;
    bottom: 15px;
    left: 15px;
    width: 122px;
    height: 158px;
    }
    @@ -71,8 +71,8 @@
    background-image: url(wind_aeolus70.png), none;
    background-repeat: no-repeat;
    position: absolute;
    top: 30px;
    left: 30px;
    top: 15px;
    left: 15px;
    width: 70px;
    height: 70px;
    -webkit-transform: rotate(30deg);
    @@ -276,10 +276,10 @@
    map.add(G.pt_layer);

    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.2);
    map.extent(bounds(data.features)).zoomBy(-0.4);

    // Start the recursive move function
    //updatePosition();
    updatePosition();
    });


  8. @jhnklly jhnklly revised this gist Aug 19, 2015. 5 changed files with 57 additions and 8 deletions.
    6 changes: 6 additions & 0 deletions gfont.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    @font-face {
    font-family: 'Stalemate';
    font-style: normal;
    font-weight: 400;
    src: local('Stalemate'), local('Stalemate-Regular'), url(http://fonts.gstatic.com/s/stalemate/v4/ILXfSNYxooD2TPt48NlaP6CWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
    }
    59 changes: 51 additions & 8 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -65,18 +65,39 @@
    height: 158px;
    }

    circle { fill: none; stroke: none; }

    #wind {
    background-image: url(wind_aeolus70.png), none;
    background-repeat: no-repeat;
    position: absolute;
    top: 30px;
    left: 30px;
    width: 70px;
    height: 70px;
    -webkit-transform: rotate(30deg);
    -moz-transform: rotate(30deg);
    -ms-transform: rotate(30deg);
    -o-transform: rotate(30deg);
    transform: rotate(30deg);
    }

    .mapsense-simple.tile-background {
    fill: RGBA(203, 230, 243, 0.75);
    }


    </style>
    </head>

    <body>

    <div id="myMap"></div>
    <div id="pane"></div>
    <!--
    <div id="test"></div>
    <div id="seadragon"></div>
    -->
    <div id="wind"></div>
    <div id="compass"></div>

    <svg>
    @@ -109,6 +130,11 @@
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>
    </filter>

    <pattern id="dragon_pattern" x="0" y="0" patternUnits="userSpaceOnUse" height="100" width="100">
    <image x="50" y="50" height="100" width="100"xlink:href="seadragon2.png"></image>
    </pattern>

    </defs>
    </svg>

    @@ -117,12 +143,10 @@

    <script>

    var key = "key-2d5eacd8b924489c8ed5e8418bd883bc";
    var map = mapsense.map("#myMap");

    var G = {};

    var basemap, grats, route, geom;
    var G = {}; // Global object for our variables
    G.key = "key-2d5eacd8b924489c8ed5e8418bd883bc";

    d3.json('ne110_graticules10.geojson', function(data) {
    G.graticule = mapsense.geoJson()
    @@ -134,7 +158,7 @@
    map.add(G.graticule);

    G.basemap = mapsense.basemap()
    .apiKey(key)
    .apiKey(G.key)
    .style('simple')
    // basemap's selection function from mapsense.js
    // plus add blur class to land
    @@ -177,7 +201,6 @@

    map.add(G.basemap);


    // A separate file and layer for the start/finish
    // we'll give them stylin' labels
    d3.json('start_finish.geojson', function(data) {
    @@ -256,10 +279,30 @@
    map.extent(bounds(data.features)).zoomBy(-0.2);

    // Start the recursive move function
    updatePosition();
    //updatePosition();
    });


    // Thar be dragons
    G.seadragon = mapsense.geoJson()
    .features([markLatLon(36.5, -73)])
    .selection(function(s){
    s.attr("class", 'sd');
    d3.select(s.node().parentNode).append("image")
    .attr("xlink:href", "seadragon2.png")
    .attr("transform",s.attr("transform"))
    .attr("x", "-50")
    .attr("y", "-50")
    .attr("width", "100")
    .attr("height", "100");

    s.attr("r", "50");
    })
    .scale("fixed");

    map.add(G.seadragon);


    // Update the attribution
    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>HatTip <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    Binary file added old_style_map.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added seadragon2.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    Binary file added wind_aeolus70.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  9. @jhnklly jhnklly revised this gist Aug 17, 2015. 3 changed files with 117 additions and 78 deletions.
    46 changes: 46 additions & 0 deletions bounds.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,46 @@
    // Hat tip Mike Bostock: https://github.com/mbostock/polymaps/blob/master/examples/bounds/bounds.js

    function bounds(features) {
    var i = -1,
    n = features.length,
    geometry,
    bounds = [{lon: Infinity, lat: Infinity}, {lon: -Infinity, lat: -Infinity}];
    while (++i < n) {
    //geometry = features[i].data.geometry;
    geometry = features[i].geometry;
    boundGeometry[geometry.type](bounds, geometry.coordinates);
    }
    return bounds;
    }

    function boundPoint(bounds, coordinate) {
    var x = coordinate[0], y = coordinate[1];
    if (x < bounds[0].lon) bounds[0].lon = x;
    if (x > bounds[1].lon) bounds[1].lon = x;
    if (y < bounds[0].lat) bounds[0].lat = y;
    if (y > bounds[1].lat) bounds[1].lat = y;
    }

    function boundPoints(bounds, coordinates) {
    var i = -1, n = coordinates.length;
    while (++i < n) boundPoint(bounds, coordinates[i]);
    }

    function boundMultiPoints(bounds, coordinates) {
    var i = -1, n = coordinates.length;
    while (++i < n) boundPoints(bounds, coordinates[i]);
    }

    var boundGeometry = {
    Point: boundPoint,
    MultiPoint: boundPoints,
    LineString: boundPoints,
    MultiLineString: boundMultiPoints,
    Polygon: function(bounds, coordinates) {
    boundPoints(bounds, coordinates[0]); // exterior ring
    },
    MultiPolygon: function(bounds, coordinates) {
    var i = -1, n = coordinates.length;
    while (++i < n) boundPoints(bounds, coordinates[i][0]);
    }
    };
    1 change: 1 addition & 0 deletions compass_jmk.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    148 changes: 70 additions & 78 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,7 @@
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script>
    <script src="https://developer.mapsense.co/mapsense.js" charset="utf-8"></script>
    <script src="bounds.js" charset="utf-8"></script>

    <link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/>
    <link type="text/css" href="simple.css" rel="stylesheet"/>
    @@ -55,7 +56,7 @@
    .oldfont { font: bold 30px Stalemate; }

    #compass {
    background-image: url(compass5.svg), none;
    background-image: url(compass_jmk.svg), none;
    background-repeat: no-repeat;
    position: absolute;
    bottom: 30px;
    @@ -74,70 +75,65 @@

    <body>

    <div id="myMap"></div>
    <div id="pane"></div>
    <div id="compass"></div>


    <svg>
    <defs id="the_defs">
    <!-- <pattern id="image_pattern" x="0" y="0" patternUnits="userSpaceOnUse" height="30" width="30">
    <image x="0" y="0" height="30" width="30" xlink:href="bike.png"></image>
    </pattern> -->

    <filter id="gblur">
    <!-- outer glow (blue) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>
    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>

    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>
    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>
    </filter>
    </defs>
    </svg>
    <div id="myMap"></div>
    <div id="pane"></div>
    <div id="compass"></div>

    <svg>
    <defs id="the_defs">
    <filter id="gblur">
    <!-- outer glow (blue) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>
    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>

    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>
    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>
    </filter>
    </defs>
    </svg>

    </body>


    <script type="text/javascript">
    <script>

    var key = "key-2d5eacd8b924489c8ed5e8418bd883bc";
    var map = mapsense.map("#myMap");

    var G = {};


    var basemap, grats, route, geom;

    d3.json('ne110_graticules10.geojson', function(data) {
    grats = mapsense.geoJson()
    G.graticule = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "graticule");
    })
    ;
    map.add(grats);
    map.add(G.graticule);

    var basemap = mapsense.basemap()
    G.basemap = mapsense.basemap()
    .apiKey(key)
    .style('simple')
    // basemap's selection function from mapsense.js
    @@ -146,7 +142,7 @@
    .selection(function(s) {
    var style = 'simple';
    var styleClass = style ? "mapsense-" + style : "";
    var zoomClass = "_" + Math.floor(basemap.map().zoom());
    var zoomClass = "_" + Math.floor(G.basemap.map().zoom());
    s.attr("class", function(feature) {
    var classes = [ styleClass, zoomClass ];
    if (feature.properties) {
    @@ -155,9 +151,7 @@
    if (feature.properties.layer == 'land' && !feature.properties.sub_layer) {
    classes = [ zoomClass, 'fadeland' ];
    if (!feature.properties.sub_layer) {
    //s.attr('filter','url(#gblur)')
    s.attr('class','')
    //.attr('filter','url(#gblur)')
    .attr('stroke','blue')
    .attr('stroke-width','4')
    .attr('paint-order', 'stroke')
    @@ -181,13 +175,17 @@

    });

    map.add(basemap);
    map.add(G.basemap);


    // A separate file and layer for the start/finish
    // we'll give them stylin' labels
    d3.json('start_finish.geojson', function(data) {
    G.start_finish = mapsense.geoJson()
    .features(data.features)
    .selection(function(s){
    s.attr("class", function(d){
    s.attr("r", "3")
    .attr("class", function(d){
    var grp = d3.select(s.node().parentNode).append("g")
    .attr("width","30")
    .attr("height","30")
    @@ -207,40 +205,34 @@
    return "point";
    });

    s.attr("r", "3")
    ;


    })
    .scale("fixed");

    map.add(G.start_finish);

    });


    G.pt_layer = mapsense.geoJson()
    .scale("fixed");



    // Route is from https://www.raceacrossamerica.org/raam
    d3.json('raamdens.geojson', function(data) {
    route = mapsense.geoJson()
    G.route = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "route");
    })
    ;
    map.add(route);
    map.add(G.route);

    geom = data.features[0].geometry;
    G.route_coordinates = data.features[0].geometry.coordinates;

    // HatTip! https://www.mapbox.com/mapbox.js/example/v1.0.0/animate-marker-along-line/

    G.j = 0;
    G.point = markLatLon(0,0); // placeholder; we'll update with route coordinates

    G.point = markLatLon(0,0); // a geojson features array

    G.pt_layer.features([G.point])
    G.pt_layer = mapsense.geoJson()
    .scale("fixed")
    .features([G.point])
    .selection(function(s){
    s.attr('class','marker');
    s.attr("r", "15");
    @@ -256,35 +248,35 @@
    .attr("y", "-25")
    .attr("width", "30")
    .attr("height", "30");

    });

    map.add(G.pt_layer);

    tick();
    });
    // Zoom to the extent of the data
    map.extent(bounds(data.features)).zoomBy(-0.2);

    // Start the recursive move function
    updatePosition();
    });

    map.add(mapsense.hash());

    // Update the attribution
    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>HatTip <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);

    });


    function tick() {
    //console.log(G.j, geom.coordinates.length);
    // Set the marker to be at the same point as one
    // of the segments or the line.
    G.point.geometry.coordinates[0] = geom.coordinates[G.j][0];
    G.point.geometry.coordinates[1] = geom.coordinates[G.j][1];
    function updatePosition() {
    // Put the marker at the line's first coordinate
    G.point.geometry.coordinates[0] = G.route_coordinates[G.j][0];
    G.point.geometry.coordinates[1] = G.route_coordinates[G.j][1];
    G.pt_layer.features([G.point]);

    // Move to the next point of the line
    // until `j` reaches the length of the array.
    if (++G.j < geom.coordinates.length) setTimeout(tick, 50);
    if (++G.j < G.route_coordinates.length) setTimeout(updatePosition, 50);
    }


  10. @jhnklly jhnklly revised this gist Aug 13, 2015. 4 changed files with 121 additions and 50 deletions.
    1 change: 1 addition & 0 deletions compass5.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    110 changes: 60 additions & 50 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -38,6 +38,8 @@
    stroke-linejoin: round;
    }

    .graticule { stroke: RGBA(153, 180, 193, 1);; }

    .marker {
    fill: none;
    stroke: none;
    @@ -53,14 +55,20 @@
    .oldfont { font: bold 30px Stalemate; }

    #compass {
    background-image: url(compass4.svg), none;
    background-image: url(compass5.svg), none;
    background-repeat: no-repeat;
    position: absolute;
    bottom: 30px;
    left: 30px;
    width: 122px;
    height: 158px;
    }

    .mapsense-simple.tile-background {
    fill: RGBA(203, 230, 243, 0.75);
    }


    </style>
    </head>

    @@ -118,62 +126,62 @@

    var G = {};

    var grats, route, geom;
    /* d3.json('ne110_graticules10.geojson', function(data) {

    var basemap, grats, route, geom;
    d3.json('ne110_graticules10.geojson', function(data) {
    grats = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "graticule");
    })
    ;
    map.add(grats);
    });*/

    var basemap = mapsense.basemap()
    .apiKey(key)
    .style('simple')
    // basemap's selection function from mapsense.js
    // plus add blur class to land
    // and change paint-order: stroke
    .selection(function(s) {
    var style = 'simple';
    var styleClass = style ? "mapsense-" + style : "";
    var zoomClass = "_" + Math.floor(basemap.map().zoom());
    s.attr("class", function(feature) {
    var classes = [ styleClass, zoomClass ];
    if (feature.properties) {
    if (feature.properties.layer)
    classes.push(feature.properties.layer);
    if (feature.properties.layer == 'land' && !feature.properties.sub_layer) {
    classes = [ zoomClass, 'fadeland' ];
    if (!feature.properties.sub_layer) {
    //s.attr('filter','url(#gblur)')
    s.attr('class','')
    //.attr('filter','url(#gblur)')
    .attr('stroke','blue')
    .attr('stroke-width','4')
    .attr('paint-order', 'stroke')
    ;
    return classes.join(" ");
    }
    }
    if (feature.properties.sub_layer)
    classes.push(feature.properties.sub_layer);
    }
    return classes.join(" ");
    });

    d3.selectAll('.fadeland')
    .attr('filter','url(#gblur)')
    .attr('class','')
    .attr('stroke','rgba(68, 167, 228, 1)')
    .attr('fill','#F5F0ED')
    .attr('stroke-width','1')
    .attr('paint-order', 'stroke')
    var basemap = mapsense.basemap()
    .apiKey(key)
    .style('simple')
    // basemap's selection function from mapsense.js
    // plus add blur class to land
    // and change paint-order: stroke
    .selection(function(s) {
    var style = 'simple';
    var styleClass = style ? "mapsense-" + style : "";
    var zoomClass = "_" + Math.floor(basemap.map().zoom());
    s.attr("class", function(feature) {
    var classes = [ styleClass, zoomClass ];
    if (feature.properties) {
    if (feature.properties.layer)
    classes.push(feature.properties.layer);
    if (feature.properties.layer == 'land' && !feature.properties.sub_layer) {
    classes = [ zoomClass, 'fadeland' ];
    if (!feature.properties.sub_layer) {
    //s.attr('filter','url(#gblur)')
    s.attr('class','')
    //.attr('filter','url(#gblur)')
    .attr('stroke','blue')
    .attr('stroke-width','4')
    .attr('paint-order', 'stroke')
    ;
    return classes.join(" ");
    }
    }
    if (feature.properties.sub_layer)
    classes.push(feature.properties.sub_layer);
    }
    return classes.join(" ");
    });

    d3.selectAll('.fadeland')
    .attr('filter','url(#gblur)')
    .attr('class','')
    .attr('stroke','rgba(68, 167, 228, 1)')
    .attr('fill','#F5F0ED')
    .attr('stroke-width','1')
    .attr('paint-order', 'stroke')

    });
    });

    map.add(basemap);
    map.add(basemap);

    d3.json('start_finish.geojson', function(data) {
    G.start_finish = mapsense.geoJson()
    @@ -259,9 +267,11 @@

    map.add(mapsense.hash());

    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>Homage to <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);
    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>HatTip <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);

    });


    function tick() {
    59 changes: 59 additions & 0 deletions ne110_graticules10.geojson
    59 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    1 change: 1 addition & 0 deletions simple.css
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,7 @@
    }
    .mapsense-simple.tile-background {
    fill: #CBE6F3;
    //fill: RGBA(203, 230, 243, 0.5);
    //fill: none;
    }
    .mapsense-simple.land {
  11. @jhnklly jhnklly revised this gist Aug 11, 2015. 2 changed files with 17 additions and 10 deletions.
    6 changes: 3 additions & 3 deletions compass4.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    21 changes: 14 additions & 7 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -42,7 +42,13 @@
    fill: none;
    stroke: none;
    }
    .mapsense-attribution { background: none; }

    .mapsense-attribution a,
    .mapsense-attribution {
    background: none;
    color: #999;
    line-height: 1em;
    }

    .oldfont { font: bold 30px Stalemate; }

    @@ -52,8 +58,8 @@
    position: absolute;
    bottom: 30px;
    left: 30px;
    width: 77px;
    height: 88px;
    width: 122px;
    height: 158px;
    }
    </style>
    </head>
    @@ -252,10 +258,11 @@


    map.add(mapsense.hash());
    /*
    var the_defs = d3.select('#the_defs');
    var defs = d3.select('.mapsense-map').append(the_defs.node());
    */

    var attrib = d3.select('.mapsense-attribution').html();
    attrib += '<br>Homage to <a target="_blank" href="http://kartograph.org/showcase/italia/">Gregor Aisch</a>';
    d3.select('.mapsense-attribution').html(attrib);


    function tick() {
    //console.log(G.j, geom.coordinates.length);
  12. @jhnklly jhnklly revised this gist Aug 11, 2015. 2 changed files with 924 additions and 0 deletions.
    913 changes: 913 additions & 0 deletions compass4.svg
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    11 changes: 11 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -45,13 +45,24 @@
    .mapsense-attribution { background: none; }

    .oldfont { font: bold 30px Stalemate; }

    #compass {
    background-image: url(compass4.svg), none;
    background-repeat: no-repeat;
    position: absolute;
    bottom: 30px;
    left: 30px;
    width: 77px;
    height: 88px;
    }
    </style>
    </head>

    <body>

    <div id="myMap"></div>
    <div id="pane"></div>
    <div id="compass"></div>


    <svg>
  13. @jhnklly jhnklly revised this gist Aug 11, 2015. 6 changed files with 216 additions and 37 deletions.
    Binary file added bike.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    218 changes: 181 additions & 37 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -7,58 +7,87 @@
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script>
    <script src="https://developer.mapsense.co/mapsense.js" charset="utf-8"></script>
    <link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/>

    <link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/>
    <link type="text/css" href="simple.css" rel="stylesheet"/>
    <link href='http://fonts.googleapis.com/css?family=Stalemate' rel='stylesheet' type='text/css'>

    <style>
    html, body, #myMap {
    html, body, #myMap, #pane {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
    font-size: 16px;
    font-family: Helvetica, Arial, sans-serif, 'Droid Sans';
    color: #666;
    position: absolute;
    }

    #pane {
    background: url(noise.png);
    pointer-events: none;
    }

    .route {
    fill: none;
    stroke: #755;
    stroke-opacity: 1;
    stroke-width: 2;
    stroke-dasharray: 5,6;
    stroke-linejoin: round;
    }

    .marker {
    fill: none;
    stroke: none;
    }
    .mapsense-attribution { background: none; }

    .oldfont { font: bold 30px Stalemate; }
    </style>
    </head>

    <body>

    <div id="myMap"></div>
    <div id="pane"></div>


    <svg>
    <defs id="the_defs">
    <filter id="gblur">
    <!-- outer glow (blue) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>
    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>

    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>
    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>

    </filter>
    <!-- <pattern id="image_pattern" x="0" y="0" patternUnits="userSpaceOnUse" height="30" width="30">
    <image x="0" y="0" height="30" width="30" xlink:href="bike.png"></image>
    </pattern> -->

    <filter id="gblur">
    <!-- outer glow (blue) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>
    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>

    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>
    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>
    </filter>
    </defs>
    </svg>

    @@ -68,6 +97,20 @@
    <script type="text/javascript">

    var key = "key-2d5eacd8b924489c8ed5e8418bd883bc";
    var map = mapsense.map("#myMap");

    var G = {};

    var grats, route, geom;
    /* d3.json('ne110_graticules10.geojson', function(data) {
    grats = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "graticule");
    })
    ;
    map.add(grats);
    });*/

    var basemap = mapsense.basemap()
    .apiKey(key)
    @@ -113,18 +156,119 @@

    });

    map.add(basemap);

    d3.json('start_finish.geojson', function(data) {
    G.start_finish = mapsense.geoJson()
    .features(data.features)
    .selection(function(s){
    s.attr("class", function(d){
    var grp = d3.select(s.node().parentNode).append("g")
    .attr("width","30")
    .attr("height","30")
    .attr("transform",d3.select(this).attr("transform"));

    var map = mapsense
    .map("#myMap")
    //.add(basebase)
    .add(basemap)
    ;
    grp.append("text")
    .data([d])
    .attr("x", "-0.1em")
    .attr("y", "0.5em")
    .attr("class", "oldfont")
    .attr("text-anchor", "middle")
    .text(function(f){
    return f.properties.name
    })
    ;

    return "point";
    });

    s.attr("r", "3")
    ;

    })
    .scale("fixed");

    map.add(G.start_finish);

    });

    map.add(mapsense.hash());

    G.pt_layer = mapsense.geoJson()
    .scale("fixed");



    d3.json('raamdens.geojson', function(data) {
    route = mapsense.geoJson()
    .features(data.features)
    .selection(function(d){
    d.attr("class", "route");
    })
    ;
    map.add(route);

    geom = data.features[0].geometry;

    // HatTip! https://www.mapbox.com/mapbox.js/example/v1.0.0/animate-marker-along-line/

    G.j = 0;

    G.point = markLatLon(0,0); // a geojson features array

    G.pt_layer.features([G.point])
    .selection(function(s){
    s.attr('class','marker');
    s.attr("r", "15");

    var grp = d3.select(s.node().parentNode).append("g")
    .attr("width","30")
    .attr("height","30")
    .attr("transform",s.attr("transform"));

    grp.append("image")
    .attr("xlink:href", "bike.png")
    .attr("x", "-10")
    .attr("y", "-25")
    .attr("width", "30")
    .attr("height", "30");

    });

    map.add(G.pt_layer);

    tick();
    });


    map.add(mapsense.hash());
    /*
    var the_defs = d3.select('#the_defs');
    var defs = d3.select('.mapsense-map').append(the_defs.node());
    */

    function tick() {
    //console.log(G.j, geom.coordinates.length);
    // Set the marker to be at the same point as one
    // of the segments or the line.
    G.point.geometry.coordinates[0] = geom.coordinates[G.j][0];
    G.point.geometry.coordinates[1] = geom.coordinates[G.j][1];
    G.pt_layer.features([G.point]);

    // Move to the next point of the line
    // until `j` reaches the length of the array.
    if (++G.j < geom.coordinates.length) setTimeout(tick, 50);
    }



    function markLatLon(lat,lon,name){
    name = name || "";
    var feature = {
    type: "Feature",
    geometry: {type: "Point", "coordinates": [ +lon, +lat ]},
    };
    return feature;
    }


    </script>
    Binary file added noise.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
    7 changes: 7 additions & 0 deletions raamdens.geojson
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    {
    "type": "FeatureCollection",

    "features": [
    { "type": "Feature", "properties": { "descriptio": null }, "geometry": { "type": "LineString", "coordinates": [ [ -117.384, 33.194, 0.0 ], [ -117.37, 33.206, 0.0 ], [ -117.356, 33.217, 0.0 ], [ -117.343, 33.228, 0.0 ], [ -117.329, 33.239, 0.0 ], [ -117.315, 33.25, 0.0 ], [ -117.301, 33.262, 0.0 ], [ -117.287, 33.273, 0.0 ], [ -117.273, 33.284, 0.0 ], [ -117.259, 33.295, 0.0 ], [ -117.245, 33.306, 0.0 ], [ -117.158, 33.301, 0.0 ], [ -117.072, 33.296, 0.0 ], [ -116.985, 33.291, 0.0 ], [ -116.898, 33.286, 0.0 ], [ -116.811, 33.281, 0.0 ], [ -116.724, 33.276, 0.0 ], [ -116.637, 33.271, 0.0 ], [ -116.55, 33.266, 0.0 ], [ -116.463, 33.262, 0.0 ], [ -116.376, 33.257, 0.0 ], [ -116.258, 33.228, 0.0 ], [ -116.139, 33.199, 0.0 ], [ -116.021, 33.17, 0.0 ], [ -115.902, 33.142, 0.0 ], [ -115.784, 33.113, 0.0 ], [ -115.665, 33.084, 0.0 ], [ -115.547, 33.055, 0.0 ], [ -115.428, 33.027, 0.0 ], [ -115.31, 32.998, 0.0 ], [ -115.191, 32.969, 0.0 ], [ -115.145, 33.004, 0.0 ], [ -115.1, 33.039, 0.0 ], [ -115.054, 33.073, 0.0 ], [ -115.008, 33.108, 0.0 ], [ -114.963, 33.143, 0.0 ], [ -114.917, 33.177, 0.0 ], [ -114.871, 33.212, 0.0 ], [ -114.825, 33.247, 0.0 ], [ -114.78, 33.281, 0.0 ], [ -114.734, 33.316, 0.0 ], [ -114.714, 33.379, 0.0 ], [ -114.695, 33.442, 0.0 ], [ -114.675, 33.505, 0.0 ], [ -114.656, 33.568, 0.0 ], [ -114.636, 33.63, 0.0 ], [ -114.617, 33.693, 0.0 ], [ -114.597, 33.756, 0.0 ], [ -114.577, 33.819, 0.0 ], [ -114.558, 33.882, 0.0 ], [ -114.538, 33.945, 0.0 ], [ -114.515, 33.965, 0.0 ], [ -114.492, 33.985, 0.0 ], [ -114.469, 34.005, 0.0 ], [ -114.446, 34.025, 0.0 ], [ -114.423, 34.046, 0.0 ], [ -114.4, 34.066, 0.0 ], [ -114.377, 34.086, 0.0 ], [ -114.354, 34.106, 0.0 ], [ -114.331, 34.126, 0.0 ], [ -114.307, 34.146, 0.0 ], [ -114.247, 34.104, 0.0 ], [ -114.186, 34.062, 0.0 ], [ -114.126, 34.019, 0.0 ], [ -114.066, 33.977, 0.0 ], [ -114.005, 33.935, 0.0 ], [ -113.945, 33.893, 0.0 ], [ -113.884, 33.85, 0.0 ], [ -113.824, 33.808, 0.0 ], [ -113.763, 33.766, 0.0 ], [ -113.703, 33.723, 0.0 ], [ -113.647, 33.745, 0.0 ], [ -113.591, 33.767, 0.0 ], [ -113.535, 33.789, 0.0 ], [ -113.479, 33.811, 0.0 ], [ -113.423, 33.833, 0.0 ], [ -113.367, 33.855, 0.0 ], [ -113.311, 33.877, 0.0 ], [ -113.255, 33.899, 0.0 ], [ -113.199, 33.921, 0.0 ], [ -113.143, 33.943, 0.0 ], [ -113.105, 33.969, 0.0 ], [ -113.066, 33.995, 0.0 ], [ -113.028, 34.021, 0.0 ], [ -112.989, 34.047, 0.0 ], [ -112.95, 34.073, 0.0 ], [ -112.912, 34.099, 0.0 ], [ -112.873, 34.125, 0.0 ], [ -112.834, 34.151, 0.0 ], [ -112.796, 34.176, 0.0 ], [ -112.757, 34.202, 0.0 ], [ -112.744, 34.242, 0.0 ], [ -112.73, 34.282, 0.0 ], [ -112.717, 34.322, 0.0 ], [ -112.703, 34.362, 0.0 ], [ -112.689, 34.402, 0.0 ], [ -112.676, 34.442, 0.0 ], [ -112.662, 34.482, 0.0 ], [ -112.649, 34.522, 0.0 ], [ -112.635, 34.561, 0.0 ], [ -112.622, 34.601, 0.0 ], [ -112.533, 34.63, 0.0 ], [ -112.444, 34.659, 0.0 ], [ -112.355, 34.687, 0.0 ], [ -112.266, 34.716, 0.0 ], [ -112.178, 34.744, 0.0 ], [ -112.089, 34.773, 0.0 ], [ -112.0, 34.802, 0.0 ], [ -111.911, 34.83, 0.0 ], [ -111.822, 34.859, 0.0 ], [ -111.734, 34.888, 0.0 ], [ -111.699, 35.006, 0.0 ], [ -111.665, 35.125, 0.0 ], [ -111.631, 35.244, 0.0 ], [ -111.597, 35.363, 0.0 ], [ -111.563, 35.482, 0.0 ], [ -111.528, 35.601, 0.0 ], [ -111.494, 35.719, 0.0 ], [ -111.46, 35.838, 0.0 ], [ -111.426, 35.957, 0.0 ], [ -111.392, 36.076, 0.0 ], [ -111.277, 36.139, 0.0 ], [ -111.163, 36.202, 0.0 ], [ -111.048, 36.265, 0.0 ], [ -110.934, 36.329, 0.0 ], [ -110.82, 36.392, 0.0 ], [ -110.705, 36.455, 0.0 ], [ -110.591, 36.518, 0.0 ], [ -110.476, 36.581, 0.0 ], [ -110.362, 36.644, 0.0 ], [ -110.247, 36.708, 0.0 ], [ -110.24, 36.738, 0.0 ], [ -110.232, 36.768, 0.0 ], [ -110.225, 36.798, 0.0 ], [ -110.217, 36.828, 0.0 ], [ -110.209, 36.858, 0.0 ], [ -110.202, 36.889, 0.0 ], [ -110.194, 36.919, 0.0 ], [ -110.186, 36.949, 0.0 ], [ -110.179, 36.979, 0.0 ], [ -110.171, 37.009, 0.0 ], [ -110.124, 37.037, 0.0 ], [ -110.076, 37.064, 0.0 ], [ -110.029, 37.092, 0.0 ], [ -109.981, 37.119, 0.0 ], [ -109.934, 37.147, 0.0 ], [ -109.886, 37.174, 0.0 ], [ -109.839, 37.202, 0.0 ], [ -109.791, 37.229, 0.0 ], [ -109.743, 37.257, 0.0 ], [ -109.696, 37.285, 0.0 ], [ -109.551, 37.292, 0.0 ], [ -109.405, 37.299, 0.0 ], [ -109.26, 37.307, 0.0 ], [ -109.115, 37.314, 0.0 ], [ -108.97, 37.322, 0.0 ], [ -108.825, 37.329, 0.0 ], [ -108.679, 37.337, 0.0 ], [ -108.534, 37.344, 0.0 ], [ -108.389, 37.352, 0.0 ], [ -108.244, 37.359, 0.0 ], [ -108.144, 37.344, 0.0 ], [ -108.044, 37.329, 0.0 ], [ -107.944, 37.314, 0.0 ], [ -107.844, 37.299, 0.0 ], [ -107.745, 37.284, 0.0 ], [ -107.645, 37.268, 0.0 ], [ -107.545, 37.253, 0.0 ], [ -107.445, 37.238, 0.0 ], [ -107.345, 37.223, 0.0 ], [ -107.246, 37.208, 0.0 ], [ -107.22, 37.214, 0.0 ], [ -107.195, 37.22, 0.0 ], [ -107.169, 37.227, 0.0 ], [ -107.144, 37.233, 0.0 ], [ -107.119, 37.239, 0.0 ], [ -107.093, 37.245, 0.0 ], [ -107.068, 37.252, 0.0 ], [ -107.043, 37.258, 0.0 ], [ -107.017, 37.264, 0.0 ], [ -106.992, 37.271, 0.0 ], [ -106.957, 37.31, 0.0 ], [ -106.922, 37.35, 0.0 ], [ -106.887, 37.39, 0.0 ], [ -106.852, 37.43, 0.0 ], [ -106.817, 37.47, 0.0 ], [ -106.782, 37.509, 0.0 ], [ -106.747, 37.549, 0.0 ], [ -106.712, 37.589, 0.0 ], [ -106.676, 37.629, 0.0 ], [ -106.641, 37.669, 0.0 ], [ -106.614, 37.67, 0.0 ], [ -106.586, 37.671, 0.0 ], [ -106.558, 37.672, 0.0 ], [ -106.531, 37.673, 0.0 ], [ -106.503, 37.674, 0.0 ], [ -106.475, 37.675, 0.0 ], [ -106.447, 37.676, 0.0 ], [ -106.42, 37.677, 0.0 ], [ -106.392, 37.679, 0.0 ], [ -106.364, 37.68, 0.0 ], [ -106.27, 37.654, 0.0 ], [ -106.177, 37.629, 0.0 ], [ -106.083, 37.604, 0.0 ], [ -105.989, 37.578, 0.0 ], [ -105.896, 37.553, 0.0 ], [ -105.802, 37.527, 0.0 ], [ -105.708, 37.502, 0.0 ], [ -105.615, 37.477, 0.0 ], [ -105.521, 37.451, 0.0 ], [ -105.427, 37.426, 0.0 ], [ -105.404, 37.445, 0.0 ], [ -105.381, 37.464, 0.0 ], [ -105.357, 37.484, 0.0 ], [ -105.334, 37.503, 0.0 ], [ -105.311, 37.522, 0.0 ], [ -105.287, 37.541, 0.0 ], [ -105.264, 37.56, 0.0 ], [ -105.241, 37.579, 0.0 ], [ -105.217, 37.598, 0.0 ], [ -105.194, 37.617, 0.0 ], [ -105.176, 37.607, 0.0 ], [ -105.157, 37.596, 0.0 ], [ -105.139, 37.585, 0.0 ], [ -105.121, 37.574, 0.0 ], [ -105.103, 37.563, 0.0 ], [ -105.084, 37.552, 0.0 ], [ -105.066, 37.542, 0.0 ], [ -105.048, 37.531, 0.0 ], [ -105.03, 37.52, 0.0 ], [ -105.011, 37.509, 0.0 ], [ -105.014, 37.473, 0.0 ], [ -105.016, 37.437, 0.0 ], [ -105.019, 37.401, 0.0 ], [ -105.021, 37.365, 0.0 ], [ -105.024, 37.329, 0.0 ], [ -105.026, 37.293, 0.0 ], [ -105.029, 37.257, 0.0 ], [ -105.031, 37.221, 0.0 ], [ -105.034, 37.185, 0.0 ], [ -105.036, 37.149, 0.0 ], [ -104.964, 37.158, 0.0 ], [ -104.892, 37.166, 0.0 ], [ -104.82, 37.175, 0.0 ], [ -104.747, 37.183, 0.0 ], [ -104.675, 37.192, 0.0 ], [ -104.603, 37.2, 0.0 ], [ -104.531, 37.209, 0.0 ], [ -104.459, 37.218, 0.0 ], [ -104.387, 37.226, 0.0 ], [ -104.315, 37.235, 0.0 ], [ -104.287, 37.224, 0.0 ], [ -104.259, 37.213, 0.0 ], [ -104.231, 37.202, 0.0 ], [ -104.204, 37.191, 0.0 ], [ -104.176, 37.18, 0.0 ], [ -104.148, 37.169, 0.0 ], [ -104.121, 37.158, 0.0 ], [ -104.093, 37.147, 0.0 ], [ -104.065, 37.136, 0.0 ], [ -104.037, 37.125, 0.0 ], [ -103.81, 37.17, 0.0 ], [ -103.582, 37.215, 0.0 ], [ -103.355, 37.26, 0.0 ], [ -103.127, 37.306, 0.0 ], [ -102.899, 37.351, 0.0 ], [ -102.672, 37.396, 0.0 ], [ -102.444, 37.442, 0.0 ], [ -102.217, 37.487, 0.0 ], [ -101.989, 37.532, 0.0 ], [ -101.762, 37.577, 0.0 ], [ -100.886, 37.613, 0.0 ], [ -100.011, 37.648, 0.0 ], [ -99.136, 37.683, 0.0 ], [ -98.26, 37.718, 0.0 ], [ -97.385, 37.753, 0.0 ], [ -96.51, 37.789, 0.0 ], [ -95.634, 37.824, 0.0 ], [ -94.759, 37.859, 0.0 ], [ -93.884, 37.894, 0.0 ], [ -93.008, 37.929, 0.0 ], [ -92.98, 37.939, 0.0 ], [ -92.951, 37.948, 0.0 ], [ -92.922, 37.958, 0.0 ], [ -92.894, 37.967, 0.0 ], [ -92.865, 37.977, 0.0 ], [ -92.836, 37.986, 0.0 ], [ -92.807, 37.996, 0.0 ], [ -92.779, 38.005, 0.0 ], [ -92.75, 38.015, 0.0 ], [ -92.721, 38.024, 0.0 ], [ -92.704, 38.058, 0.0 ], [ -92.686, 38.092, 0.0 ], [ -92.668, 38.126, 0.0 ], [ -92.651, 38.16, 0.0 ], [ -92.633, 38.193, 0.0 ], [ -92.616, 38.227, 0.0 ], [ -92.598, 38.261, 0.0 ], [ -92.581, 38.295, 0.0 ], [ -92.563, 38.328, 0.0 ], [ -92.546, 38.362, 0.0 ], [ -92.508, 38.386, 0.0 ], [ -92.47, 38.41, 0.0 ], [ -92.432, 38.433, 0.0 ], [ -92.394, 38.457, 0.0 ], [ -92.356, 38.481, 0.0 ], [ -92.318, 38.505, 0.0 ], [ -92.28, 38.528, 0.0 ], [ -92.242, 38.552, 0.0 ], [ -92.204, 38.576, 0.0 ], [ -92.167, 38.599, 0.0 ], [ -92.095, 38.612, 0.0 ], [ -92.023, 38.625, 0.0 ], [ -91.951, 38.638, 0.0 ], [ -91.879, 38.651, 0.0 ], [ -91.807, 38.664, 0.0 ], [ -91.735, 38.677, 0.0 ], [ -91.663, 38.69, 0.0 ], [ -91.591, 38.703, 0.0 ], [ -91.519, 38.716, 0.0 ], [ -91.447, 38.729, 0.0 ], [ -91.402, 38.71, 0.0 ], [ -91.358, 38.691, 0.0 ], [ -91.314, 38.672, 0.0 ], [ -91.27, 38.653, 0.0 ], [ -91.226, 38.634, 0.0 ], [ -91.182, 38.615, 0.0 ], [ -91.138, 38.596, 0.0 ], [ -91.094, 38.576, 0.0 ], [ -91.05, 38.557, 0.0 ], [ -91.006, 38.538, 0.0 ], [ -90.99, 38.566, 0.0 ], [ -90.975, 38.593, 0.0 ], [ -90.96, 38.62, 0.0 ], [ -90.945, 38.647, 0.0 ], [ -90.929, 38.674, 0.0 ], [ -90.914, 38.702, 0.0 ], [ -90.899, 38.729, 0.0 ], [ -90.883, 38.756, 0.0 ], [ -90.868, 38.783, 0.0 ], [ -90.853, 38.811, 0.0 ], [ -90.803, 38.821, 0.0 ], [ -90.753, 38.831, 0.0 ], [ -90.703, 38.841, 0.0 ], [ -90.652, 38.851, 0.0 ], [ -90.602, 38.861, 0.0 ], [ -90.552, 38.871, 0.0 ], [ -90.502, 38.881, 0.0 ], [ -90.452, 38.891, 0.0 ], [ -90.402, 38.901, 0.0 ], [ -90.352, 38.911, 0.0 ], [ -90.256, 38.907, 0.0 ], [ -90.16, 38.904, 0.0 ], [ -90.064, 38.901, 0.0 ], [ -89.967, 38.898, 0.0 ], [ -89.871, 38.895, 0.0 ], [ -89.775, 38.892, 0.0 ], [ -89.679, 38.888, 0.0 ], [ -89.583, 38.885, 0.0 ], [ -89.487, 38.882, 0.0 ], [ -89.39, 38.879, 0.0 ], [ -89.307, 38.903, 0.0 ], [ -89.223, 38.927, 0.0 ], [ -89.14, 38.951, 0.0 ], [ -89.057, 38.975, 0.0 ], [ -88.973, 39.0, 0.0 ], [ -88.89, 39.024, 0.0 ], [ -88.806, 39.048, 0.0 ], [ -88.723, 39.072, 0.0 ], [ -88.639, 39.096, 0.0 ], [ -88.556, 39.12, 0.0 ], [ -88.52, 39.107, 0.0 ], [ -88.485, 39.094, 0.0 ], [ -88.45, 39.081, 0.0 ], [ -88.414, 39.069, 0.0 ], [ -88.379, 39.056, 0.0 ], [ -88.343, 39.043, 0.0 ], [ -88.308, 39.03, 0.0 ], [ -88.273, 39.017, 0.0 ], [ -88.237, 39.004, 0.0 ], [ -88.202, 38.991, 0.0 ], [ -88.144, 39.004, 0.0 ], [ -88.086, 39.017, 0.0 ], [ -88.028, 39.03, 0.0 ], [ -87.971, 39.043, 0.0 ], [ -87.913, 39.056, 0.0 ], [ -87.855, 39.069, 0.0 ], [ -87.797, 39.082, 0.0 ], [ -87.74, 39.095, 0.0 ], [ -87.682, 39.108, 0.0 ], [ -87.624, 39.121, 0.0 ], [ -87.536, 39.113, 0.0 ], [ -87.448, 39.105, 0.0 ], [ -87.359, 39.097, 0.0 ], [ -87.271, 39.088, 0.0 ], [ -87.183, 39.08, 0.0 ], [ -87.095, 39.072, 0.0 ], [ -87.007, 39.064, 0.0 ], [ -86.918, 39.056, 0.0 ], [ -86.83, 39.047, 0.0 ], [ -86.742, 39.039, 0.0 ], [ -86.736, 39.052, 0.0 ], [ -86.73, 39.065, 0.0 ], [ -86.724, 39.079, 0.0 ], [ -86.718, 39.092, 0.0 ], [ -86.712, 39.105, 0.0 ], [ -86.706, 39.118, 0.0 ], [ -86.7, 39.131, 0.0 ], [ -86.693, 39.144, 0.0 ], [ -86.687, 39.157, 0.0 ], [ -86.681, 39.171, 0.0 ], [ -86.535, 39.184, 0.0 ], [ -86.389, 39.198, 0.0 ], [ -86.242, 39.211, 0.0 ], [ -86.096, 39.225, 0.0 ], [ -85.95, 39.238, 0.0 ], [ -85.803, 39.252, 0.0 ], [ -85.657, 39.265, 0.0 ], [ -85.511, 39.279, 0.0 ], [ -85.364, 39.293, 0.0 ], [ -85.218, 39.306, 0.0 ], [ -85.171, 39.326, 0.0 ], [ -85.124, 39.346, 0.0 ], [ -85.077, 39.367, 0.0 ], [ -85.03, 39.387, 0.0 ], [ -84.984, 39.407, 0.0 ], [ -84.937, 39.427, 0.0 ], [ -84.89, 39.447, 0.0 ], [ -84.843, 39.467, 0.0 ], [ -84.796, 39.487, 0.0 ], [ -84.749, 39.507, 0.0 ], [ -84.675, 39.486, 0.0 ], [ -84.6, 39.464, 0.0 ], [ -84.526, 39.442, 0.0 ], [ -84.452, 39.42, 0.0 ], [ -84.377, 39.398, 0.0 ], [ -84.303, 39.376, 0.0 ], [ -84.228, 39.355, 0.0 ], [ -84.154, 39.333, 0.0 ], [ -84.079, 39.311, 0.0 ], [ -84.005, 39.289, 0.0 ], [ -83.915, 39.295, 0.0 ], [ -83.826, 39.302, 0.0 ], [ -83.736, 39.308, 0.0 ], [ -83.647, 39.315, 0.0 ], [ -83.557, 39.321, 0.0 ], [ -83.467, 39.328, 0.0 ], [ -83.378, 39.334, 0.0 ], [ -83.288, 39.341, 0.0 ], [ -83.198, 39.347, 0.0 ], [ -83.109, 39.354, 0.0 ], [ -83.022, 39.339, 0.0 ], [ -82.934, 39.325, 0.0 ], [ -82.847, 39.311, 0.0 ], [ -82.76, 39.296, 0.0 ], [ -82.672, 39.282, 0.0 ], [ -82.585, 39.268, 0.0 ], [ -82.498, 39.254, 0.0 ], [ -82.411, 39.239, 0.0 ], [ -82.323, 39.225, 0.0 ], [ -82.236, 39.211, 0.0 ], [ -82.222, 39.223, 0.0 ], [ -82.207, 39.236, 0.0 ], [ -82.193, 39.249, 0.0 ], [ -82.179, 39.261, 0.0 ], [ -82.165, 39.274, 0.0 ], [ -82.15, 39.287, 0.0 ], [ -82.136, 39.299, 0.0 ], [ -82.122, 39.312, 0.0 ], [ -82.108, 39.325, 0.0 ], [ -82.094, 39.337, 0.0 ], [ -82.068, 39.325, 0.0 ], [ -82.042, 39.312, 0.0 ], [ -82.016, 39.3, 0.0 ], [ -81.99, 39.287, 0.0 ], [ -81.964, 39.275, 0.0 ], [ -81.938, 39.262, 0.0 ], [ -81.913, 39.25, 0.0 ], [ -81.887, 39.237, 0.0 ], [ -81.861, 39.225, 0.0 ], [ -81.835, 39.212, 0.0 ], [ -81.615, 39.22, 0.0 ], [ -81.395, 39.228, 0.0 ], [ -81.174, 39.236, 0.0 ], [ -80.954, 39.244, 0.0 ], [ -80.734, 39.252, 0.0 ], [ -80.514, 39.26, 0.0 ], [ -80.294, 39.268, 0.0 ], [ -80.073, 39.276, 0.0 ], [ -79.853, 39.284, 0.0 ], [ -79.633, 39.292, 0.0 ], [ -79.615, 39.294, 0.0 ], [ -79.597, 39.296, 0.0 ], [ -79.579, 39.297, 0.0 ], [ -79.56, 39.299, 0.0 ], [ -79.542, 39.301, 0.0 ], [ -79.524, 39.303, 0.0 ], [ -79.506, 39.305, 0.0 ], [ -79.488, 39.307, 0.0 ], [ -79.47, 39.309, 0.0 ], [ -79.451, 39.311, 0.0 ], [ -79.428, 39.351, 0.0 ], [ -79.404, 39.39, 0.0 ], [ -79.381, 39.43, 0.0 ], [ -79.357, 39.469, 0.0 ], [ -79.334, 39.509, 0.0 ], [ -79.31, 39.548, 0.0 ], [ -79.287, 39.588, 0.0 ], [ -79.263, 39.627, 0.0 ], [ -79.24, 39.666, 0.0 ], [ -79.216, 39.706, 0.0 ], [ -79.102, 39.706, 0.0 ], [ -78.988, 39.706, 0.0 ], [ -78.873, 39.706, 0.0 ], [ -78.759, 39.706, 0.0 ], [ -78.645, 39.706, 0.0 ], [ -78.531, 39.705, 0.0 ], [ -78.417, 39.705, 0.0 ], [ -78.302, 39.705, 0.0 ], [ -78.188, 39.705, 0.0 ], [ -78.074, 39.705, 0.0 ], [ -78.063, 39.722, 0.0 ], [ -78.051, 39.738, 0.0 ], [ -78.039, 39.755, 0.0 ], [ -78.028, 39.771, 0.0 ], [ -78.016, 39.788, 0.0 ], [ -78.005, 39.804, 0.0 ], [ -77.993, 39.821, 0.0 ], [ -77.982, 39.837, 0.0 ], [ -77.97, 39.854, 0.0 ], [ -77.959, 39.87, 0.0 ], [ -77.91, 39.856, 0.0 ], [ -77.861, 39.842, 0.0 ], [ -77.812, 39.827, 0.0 ], [ -77.763, 39.813, 0.0 ], [ -77.714, 39.799, 0.0 ], [ -77.665, 39.784, 0.0 ], [ -77.616, 39.77, 0.0 ], [ -77.567, 39.756, 0.0 ], [ -77.518, 39.742, 0.0 ], [ -77.469, 39.727, 0.0 ], [ -77.419, 39.734, 0.0 ], [ -77.37, 39.74, 0.0 ], [ -77.321, 39.747, 0.0 ], [ -77.271, 39.754, 0.0 ], [ -77.222, 39.76, 0.0 ], [ -77.172, 39.767, 0.0 ], [ -77.123, 39.773, 0.0 ], [ -77.074, 39.78, 0.0 ], [ -77.024, 39.786, 0.0 ], [ -76.975, 39.793, 0.0 ], [ -76.966, 39.78, 0.0 ], [ -76.957, 39.767, 0.0 ], [ -76.949, 39.754, 0.0 ], [ -76.94, 39.741, 0.0 ], [ -76.931, 39.729, 0.0 ], [ -76.922, 39.716, 0.0 ], [ -76.913, 39.703, 0.0 ], [ -76.904, 39.69, 0.0 ], [ -76.895, 39.677, 0.0 ], [ -76.887, 39.664, 0.0 ], [ -76.913, 39.624, 0.0 ], [ -76.939, 39.583, 0.0 ], [ -76.965, 39.543, 0.0 ], [ -76.991, 39.502, 0.0 ], [ -77.017, 39.461, 0.0 ], [ -77.043, 39.421, 0.0 ], [ -77.069, 39.38, 0.0 ], [ -77.095, 39.339, 0.0 ], [ -77.122, 39.299, 0.0 ], [ -77.148, 39.258, 0.0 ], [ -77.081, 39.23, 0.0 ], [ -77.015, 39.202, 0.0 ], [ -76.949, 39.174, 0.0 ], [ -76.883, 39.146, 0.0 ], [ -76.817, 39.118, 0.0 ], [ -76.751, 39.09, 0.0 ], [ -76.684, 39.062, 0.0 ], [ -76.618, 39.033, 0.0 ], [ -76.552, 39.005, 0.0 ], [ -76.486, 38.977, 0.0 ] ] } }
    ]
    }
    1 change: 1 addition & 0 deletions simple.css
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,7 @@
    }
    .mapsense-simple.tile-background {
    fill: #CBE6F3;
    //fill: none;
    }
    .mapsense-simple.land {
    fill: #ffffff;
    27 changes: 27 additions & 0 deletions start_finish.geojson
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    {
    "type": "FeatureCollection",
    "features": [
    {
    "type": "Feature",
    "properties": { "name": "Oceanside"},
    "geometry": {
    "type": "Point",
    "coordinates": [
    -117.3794834,
    33.1958696
    ]
    }
    },
    {
    "type": "Feature",
    "properties": { "name": "Annapolis"},
    "geometry": {
    "type": "Point",
    "coordinates": [
    -76.492786,
    38.9786401
    ]
    }
    }
    ]
    }
  14. mapsense-examples created this gist Aug 6, 2015.
    131 changes: 131 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,131 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content='initial-scale=1,maximum-scale=1,user-scalable=no' />

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://d3js.org/topojson.v1.min.js" charset="utf-8"></script>
    <script src="https://developer.mapsense.co/mapsense.js" charset="utf-8"></script>
    <link type="text/css" href="https://developer.mapsense.co/mapsense.css" rel="stylesheet"/>

    <link type="text/css" href="simple.css" rel="stylesheet"/>
    <style>
    html, body, #myMap {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
    font-size: 16px;
    font-family: Helvetica, Arial, sans-serif, 'Droid Sans';
    color: #666;
    }

    </style>
    </head>

    <body>
    <div id="myMap"></div>


    <svg>
    <defs id="the_defs">
    <filter id="gblur">
    <!-- outer glow (blue) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="dilate" result="mask"></feMorphology>
    <feColorMatrix in="mask" type="matrix" values="0 0 0 0.26 0 0 0 0 0.65 0 0 0 0 0.89 0 0 0 0 500 0" result="r0"></feColorMatrix>
    <feGaussianBlur in="r0" stdDeviation="4" result="r1"></feGaussianBlur>
    <feComposite operator="out" in="r1" in2="mask" result="comp"></feComposite>
    <feMerge result="oglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="r1"></feMergeNode>
    </feMerge>

    <!-- inner glow (brown) -->
    <feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 0" result="mask"></feColorMatrix>
    <feMorphology in="mask" radius="1" operator="erode" result="r1"></feMorphology>
    <feGaussianBlur in="r1" stdDeviation="4" result="r2"></feGaussianBlur>
    <feColorMatrix in="r2" type="matrix" values="1 0 0 0 0.58 0 1 0 0 0.36 0 0 1 0 0.106 0 0 0 -1 1" result="r3"></feColorMatrix>
    <feComposite operator="in" in="r3" in2="mask" result="comp"></feComposite>
    <feMerge result="myglow">
    <feMergeNode in="SourceGraphic"></feMergeNode>
    <feMergeNode in="comp"></feMergeNode>
    </feMerge>

    <feMerge result="the_gblur">
    <feMergeNode in="oglow"></feMergeNode>
    <feMergeNode in="myglow"></feMergeNode>
    </feMerge>

    </filter>
    </defs>
    </svg>

    </body>


    <script type="text/javascript">

    var key = "key-2d5eacd8b924489c8ed5e8418bd883bc";

    var basemap = mapsense.basemap()
    .apiKey(key)
    .style('simple')
    // basemap's selection function from mapsense.js
    // plus add blur class to land
    // and change paint-order: stroke
    .selection(function(s) {
    var style = 'simple';
    var styleClass = style ? "mapsense-" + style : "";
    var zoomClass = "_" + Math.floor(basemap.map().zoom());
    s.attr("class", function(feature) {
    var classes = [ styleClass, zoomClass ];
    if (feature.properties) {
    if (feature.properties.layer)
    classes.push(feature.properties.layer);
    if (feature.properties.layer == 'land' && !feature.properties.sub_layer) {
    classes = [ zoomClass, 'fadeland' ];
    if (!feature.properties.sub_layer) {
    //s.attr('filter','url(#gblur)')
    s.attr('class','')
    //.attr('filter','url(#gblur)')
    .attr('stroke','blue')
    .attr('stroke-width','4')
    .attr('paint-order', 'stroke')
    ;
    return classes.join(" ");
    }
    }
    if (feature.properties.sub_layer)
    classes.push(feature.properties.sub_layer);
    }
    return classes.join(" ");
    });

    d3.selectAll('.fadeland')
    .attr('filter','url(#gblur)')
    .attr('class','')
    .attr('stroke','rgba(68, 167, 228, 1)')
    .attr('fill','#F5F0ED')
    .attr('stroke-width','1')
    .attr('paint-order', 'stroke')

    });



    var map = mapsense
    .map("#myMap")
    //.add(basebase)
    .add(basemap)
    ;

    map.add(mapsense.hash());

    var the_defs = d3.select('#the_defs');
    var defs = d3.select('.mapsense-map').append(the_defs.node());


    </script>
    </html>
    102 changes: 102 additions & 0 deletions simple.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    .mapsense-simple.labels {
    font-size: 14;
    fill: #777;
    font-weight: 600;
    text-transform: uppercase;
    stroke-width: .3;
    font-stretch: expanded;
    letter-spacing: 1.5;
    font-family: "Josefin Sans";
    }
    .mapsense-simple.tile-background {
    fill: #CBE6F3;
    }
    .mapsense-simple.land {
    fill: #ffffff;
    stroke: #a2d3f2;
    stroke-width: 1;
    }
    .mapsense-simple.water_polygon {
    fill: #CBE6F3;
    stroke: #b6d3e0;
    stroke-width: 0.5px;
    }
    .mapsense-simple.water_line {
    stroke: #a2d3f2;
    }
    .mapsense-simple.park {
    fill: none;
    stroke-width: 0;
    stroke: #dad8d8;
    }
    .mapsense-simple.landuse {
    fill: none;
    stroke: none;
    }
    .mapsense-simple.building {
    fill: none;
    stroke: #d4d4d4;
    stroke-width: .52;
    }
    .mapsense-simple.school {
    fill: none;
    stroke: none;
    }
    .mapsense-simple.other {
    fill: none;
    stroke: none;
    }
    .mapsense-simple.urban {
    fill: none;
    stroke: none;
    }
    .mapsense-simple.ne_10m_roads {
    stroke: #eee;
    }
    .mapsense-simple.motorway {
    stroke: #ddd;
    }
    .mapsense-simple.arterial_major {
    stroke: #eee;
    }
    .mapsense-simple.arterial_minor {
    stroke: #eee;
    }
    .mapsense-simple.road_med {
    stroke: #eee;
    }
    .mapsense-simple.road_minor {
    stroke: #f5f5f5;
    }
    .mapsense-simple.rail_major {
    stroke: #ddd;
    }
    .mapsense-simple.rail_minor {
    stroke: #ddd;
    }
    .mapsense-simple.runway {
    stroke: #ddd;
    }
    .mapsense-simple.path {
    stroke: #f5f5f5;
    }
    .mapsense-simple.country_border,
    .mapsense-simple.disputed_border {
    stroke: #ccc;
    }
    .mapsense-simple.state_border {
    stroke: #ccc;
    }
    .mapsense-simple.ne_10m_roads._3 {
    stroke-width: 0.5;
    stroke: none;
    }
    .mapsense-simple.ne_10m_roads._4,
    .mapsense-simple.ne_10m_roads._5 {
    stroke-width: 0.75;
    stroke: none;
    }
    .mapsense-simple.ne_10m_roads._6 {
    opacity: 0.75;
    stroke: none;
    }