jQueryGeo / geo

Small, fast & simple JavaScript mapping and geospatial API as a jQuery plugin
http://docs.jquerygeo.com
MIT License
422 stars 74 forks source link

Zoom level based on distance of path drawn on map #153

Open zsk5386 opened 10 years ago

zsk5386 commented 10 years ago

Hi again!

So I'm using jQueryGeo to show a user's path that he has driven. I append points and linestrings to the map to show the user's path. What I would like to do is make the map have the correct amount of zoom based on the distance of the user's path. For example, if the path is across the United States, the map will have to be zoomed out a lot more (so you can see the entire path) than if the user's path was to the supermarket down the street (in which case the map would have to be zoomed in a lot more).

Do you have any advice on how to do something like this? How many kilometers exactly is each zoom level? Maybe I can write some jQuery to determine the distance between the start and end points of the path and, if the total distance falls within the kilometer range of a certain zoom level, choose that map zoom level. But I would have to know the kilometer distance for each zoom level.

ryanttb commented 10 years ago

Setting the bbox of the map will pick the best zoom level to show that bounding box. An easy way to get the bbox of a bunch of shapes is to add them to a GeometryCollection ( http://geojson.org/geojson-spec.html#geometry-collection ) and then use the $.geo.bbox function ( http://docs.jquerygeo.com/geo/bbox.html ).

Assuming the shapes you're appending are already in an array named shapes, you can do something like the following. I recommend calculating the bbox before creating the map so you can set the bbox at the same time as initializing the widget (which avoids requesting unnecessary map tiles). I'm also using $.geo.scaleBy to increase the bbox a little because sometimes the fit is too tight and you miss the edge of some shapes.

// assumed to be an array of the shapes you're adding
var shapes = [ { type: 'Point', coordinates: [ ] }, ... ];

var geomCol = {
  type: 'GeometryCollection',
  geometries: shapes
};
var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 );

var map = $("#map").geomap({
  bbox: bbox
});

map.geomap( 'append', geomCol );
zsk5386 commented 10 years ago

Thanks a lot! I'm super busy at work the next two weeks but I'll try out your solution asap. I really appreciate it. On Mar 1, 2014 8:37 AM, "Ryan Westphal" notifications@github.com wrote:

Setting the bbox of the map will pick the best zoom level to show that bounding box. An easy way to get the bbox of a bunch of shapes is to add them to a GeometryCollection ( http://geojson.org/geojson-spec.html#geometry-collection ) and then use the $.geo.bbox function ( http://docs.jquerygeo.com/geo/bbox.html ).

Assuming the shapes you're appending are already in an array named shapes, you can do something like the following. I recommend calculating the bbox before creating the map so you can set the bbox at the same time as initializing the widget (which avoids requesting unnecessary map tiles). I'm also using $.geo.scaleBy to increase the bbox a little because sometimes the fit is too tight and you miss the edge of some shapes.

// assumed to be an array of the shapes you're addingvar shapes = [ { type: 'Point', coordinates: [ ] }, ... ]; var geomCol = { type: 'GeometryCollection', geometries: shapes};var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); var map = $("#map").geomap({ bbox: bbox}); map.geomap( 'append', geomCol );

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36429224 .

zsk5386 commented 10 years ago

I'm having some trouble getting this solution to work, probably because I'm not quite sure how to add shapes to the Shapes array. I have used the following code, but the map isn't even showing up, much less the shapes:

// ------------------------------------------------/ // ---------------->>> MAP STUFF <<<---------------/ // ------------------------------------------------*/ //------------------------------------draw items on map-------------------------------------

// set up var numPoints = $('.info_content_row').length; var i = 0;

// needed for drawing lines between points var lastLat = 0; var lastLong = 0;

// create array for geometries var shapes = []; //set up start and end trail images var startTrail = $("#start_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } ); var endTrail = $("#end_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } );

$( ".info_content_row" ).each(function( index ) { var lat = $(this).find('.GPS1').val(); var long = $(this).find('.GPS2').val();

if (i == 0) // start point { // create start point shapes.add({type: "Point", coordinates: [lat, long]}); } else if (i == numPoints-1) // end point { //create end point shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); } else { shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); }

lastLat = lat; lastLong = long; i++; });

//---------------------------------------set up map------------------------------------------------- var geomCol = { type: 'GeometryCollection', geometries: shapes }; var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); // bbox sets boundaries/zoom/centering

//---------------------------------------set up map-------------------------------------

$("#map").geomap({ zoomMin: 4, bbox: bbox, scroll: "off",

// an array of service objects services: [ { type: "tiled", src: function( view ) { return "http://otile" + ((view.index % 4) + 1) + ". mqcdn.com/tiles/1.0.0/osm/" + view.zoom + "/" + view.tile.column + "/" + view.tile.row + ".png"; } },

      // a service where we draw start trail as CSS markers
      {
        id: "start_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw end trail as CSS markers
      {
        id: "end_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "lineMark",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "marker",
        type: "tiled",
        src: ""
      }

    ]

});

map.geomap( 'append', geomCol );

On Sat, Mar 1, 2014 at 1:22 PM, Zac K zsk5386@gmail.com wrote:

Thanks a lot! I'm super busy at work the next two weeks but I'll try out your solution asap. I really appreciate it. On Mar 1, 2014 8:37 AM, "Ryan Westphal" notifications@github.com wrote:

Setting the bbox of the map will pick the best zoom level to show that bounding box. An easy way to get the bbox of a bunch of shapes is to add them to a GeometryCollection ( http://geojson.org/geojson-spec.html#geometry-collection ) and then use the $.geo.bbox function ( http://docs.jquerygeo.com/geo/bbox.html ).

Assuming the shapes you're appending are already in an array named shapes, you can do something like the following. I recommend calculating the bbox before creating the map so you can set the bbox at the same time as initializing the widget (which avoids requesting unnecessary map tiles). I'm also using $.geo.scaleBy to increase the bbox a little because sometimes the fit is too tight and you miss the edge of some shapes.

// assumed to be an array of the shapes you're addingvar shapes = [ { type: 'Point', coordinates: [ ] }, ... ]; var geomCol = { type: 'GeometryCollection', geometries: shapes};var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); var map = $("#map").geomap({ bbox: bbox}); map.geomap( 'append', geomCol );

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36429224 .

zsk5386 commented 10 years ago

Essentially, I'm getting a bunch of GPS points (which works) and trying to draw them, and lines between them, on the map. The first point should use the startTrail service and the last point should use the endTrail service, which each have a little icon to show the start / end of the trip.

On Mon, Mar 3, 2014 at 8:59 AM, Zac K zsk5386@gmail.com wrote:

I'm having some trouble getting this solution to work, probably because I'm not quite sure how to add shapes to the Shapes array. I have used the following code, but the map isn't even showing up, much less the shapes:

// ------------------------------------------------/ // ---------------->>> MAP STUFF <<<---------------/ // ------------------------------------------------*/ //------------------------------------draw items on map-------------------------------------

// set up var numPoints = $('.info_content_row').length; var i = 0;

// needed for drawing lines between points var lastLat = 0; var lastLong = 0;

// create array for geometries var shapes = []; //set up start and end trail images var startTrail = $("#start_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } ); var endTrail = $("#end_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } );

$( ".info_content_row" ).each(function( index ) { var lat = $(this).find('.GPS1').val(); var long = $(this).find('.GPS2').val();

if (i == 0) // start point { // create start point shapes.add({type: "Point", coordinates: [lat, long]}); } else if (i == numPoints-1) // end point { //create end point shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); } else { shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); }

lastLat = lat; lastLong = long; i++; });

//---------------------------------------set up map------------------------------------------------- var geomCol = { type: 'GeometryCollection', geometries: shapes }; var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); // bbox sets boundaries/zoom/centering

//---------------------------------------set up map-------------------------------------

$("#map").geomap({ zoomMin: 4, bbox: bbox, scroll: "off",

// an array of service objects services: [ { type: "tiled", src: function( view ) { return "http://otile" + ((view.index % 4) + 1) + ". mqcdn.com/tiles/1.0.0/osm/" + view.zoom + "/" + view.tile.column + "/" + view.tile.row + ".png"; } },

      // a service where we draw start trail as CSS markers
      {
        id: "start_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw end trail as CSS markers
      {
        id: "end_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "lineMark",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "marker",
        type: "tiled",
        src: ""
      }

    ]

});

map.geomap( 'append', geomCol );

On Sat, Mar 1, 2014 at 1:22 PM, Zac K zsk5386@gmail.com wrote:

Thanks a lot! I'm super busy at work the next two weeks but I'll try out your solution asap. I really appreciate it. On Mar 1, 2014 8:37 AM, "Ryan Westphal" notifications@github.com wrote:

Setting the bbox of the map will pick the best zoom level to show that bounding box. An easy way to get the bbox of a bunch of shapes is to add them to a GeometryCollection ( http://geojson.org/geojson-spec.html#geometry-collection ) and then use the $.geo.bbox function ( http://docs.jquerygeo.com/geo/bbox.html ).

Assuming the shapes you're appending are already in an array named shapes, you can do something like the following. I recommend calculating the bbox before creating the map so you can set the bbox at the same time as initializing the widget (which avoids requesting unnecessary map tiles). I'm also using $.geo.scaleBy to increase the bbox a little because sometimes the fit is too tight and you miss the edge of some shapes.

// assumed to be an array of the shapes you're addingvar shapes = [ { type: 'Point', coordinates: [ ] }, ... ]; var geomCol = { type: 'GeometryCollection', geometries: shapes};var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); var map = $("#map").geomap({ bbox: bbox}); map.geomap( 'append', geomCol );

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36429224 .

zsk5386 commented 10 years ago

The old code used to be:

// ------------------------------------------------/ // ---------------->>> MAP STUFF <<<---------------/ // ------------------------------------------------*/ //---------------------------------------set up map-------------------------------------

$("#map").geomap({
    zoomMin: 4,
    scroll: "off",

  // an array of service objects
    services: [
      {
        type: "tiled",
        src: function( view ) {
          return "http://otile" + ((view.index % 4) + 1) +

".mqcdn.com/tiles/1.0.0/osm/" + view.zoom + "/" + view.tile.column + "/" + view.tile.row + ".png"; } },

      // a service where we draw start trail as CSS markers
      {
        id: "start_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw end trail as CSS markers
      {
        id: "end_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "lineMark",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "marker",
        type: "tiled",
        src: ""
      }

    ]
});

//------------------------------------draw items on

map-------------------------------------

// set up
var numPoints = $('.info_content_row').length;
var i = 0;

// needed for drawing lines between points
var lastLat = 0;
var lastLong = 0;

// create array to determine centering point for map
var $mapCenterArrayLat = [];
var $mapCenterArrayLong = [];

$( ".info_content_row" ).each(function( index )
{
    var lat = $(this).find('.GPS1').val();
    var long = $(this).find('.GPS2').val();

    $mapCenterArrayLat.push(lat);   // add to array
    $mapCenterArrayLong.push(long);  // add to array

    if (i == 0) // start point
    {
        // create start point
        var startTrail = $("#start_trail").geomap( "option", "shapeStyle",

{ width: 0, height: 0 } ); startTrail.geomap( "append", { type: "Point", coordinates: [lat, long] }, "" );

        //append START point
        $("#map").geomap( "append", {
            type: "Feature",
            geometry: {
                type: "Point",
                coordinates: [lat, long]
            }
        })
    }
    else if (i == numPoints-1)  // end point
    {
        //create end point
        var endTrail = $("#end_trail").geomap( "option", "shapeStyle", {

width: 0, height: 0 } ); endTrail.geomap( "append", { type: "Point", coordinates: [lat, long] }, "" );

        //append END point
        $("#map").geomap( "append", {
            type: "Feature",
            geometry: {
                type: "Point",
                coordinates: [lat, long]
            }
        })

        //append red line
        $("#lineMark").geomap( "append", {
            type: "LineString",
                coordinates: [
                    [lastLat, lastLong],
                    [lat, long]
                ],
        }, { strokeWidth: "5px" })
    }
    else
    {
        $("#map").geomap( "append", {
            type: "Feature",
            geometry: {
                type: "Point",
                coordinates: [lat, long ]
            }
        })

        //append red line
        $("#lineMark").geomap( "append", {
            type: "LineString",
                coordinates: [
                    [lastLat, lastLong],
                    [lat, long]
                ],
        }, { strokeWidth: "5px" })
    }

    lastLat = lat;
    lastLong = long;
    i++;
});

//-------------------------calculate center point and center

map----------------------------------------- $mapCenterArrayLat.sort(function(a, b) { // sort from smallest to largest if (isNaN(a) || isNaN(b)) { if (a > b) return 1; else return -1; } return a - b; });

$mapCenterArrayLong.sort(function(a, b) {  // sort from smallest to largest
    if (isNaN(a) || isNaN(b)) {
            if (a > b) return 1;
            else return -1;
    }
    return a - b;
});

var centerLat = (parseFloat($mapCenterArrayLat[0]) +

parseFloat($mapCenterArrayLat[$mapCenterArrayLat.length - 1]))/2; // add and divide by 2 var centerLong = (parseFloat($mapCenterArrayLong[0]) + parseFloat($mapCenterArrayLong[$mapCenterArrayLong.length - 1]))/2; // add and divide by 2

        // actually setting the map's center point is farther down the code

//---------------------------------------calculate

zoom------------------------------------------------- var zoom_amt = 12; //default zoom

var distance = haversine($mapCenterArrayLat[0],

$mapCenterArrayLong[0], $mapCenterArrayLat[$mapCenterArrayLat.length - 1], $mapCenterArrayLong[$mapCenterArrayLong.length - 1]); //use haversine formula to get distance

if (distance < 1)  //tested and looks good
{
    zoom_amt = 18;
}
if (distance >= 2 && distance < 5)  //tested and looks good
{
    zoom_amt = 14;
}
if (distance >= 5 && distance < 12)  //tested and looks good
{
    zoom_amt = 13;
}
if (distance >= 12 && distance < 20)
{
    zoom_amt = 12;
}
if (distance >= 20 && distance < 100)
{
    zoom_amt = 11;
}
if (distance >= 100 && distance < 300)
{
    zoom_amt = 10;
}
if (distance >= 300 && distance < 800)
{
    zoom_amt = 9;
}
if (distance >= 800 && distance < 1100)
{
    zoom_amt = 8;
}
if (distance >= 1100 && distance < 1200)
{
    zoom_amt = 7;
}
if (distance >= 1200 && distance < 1600)  //tested and looks good
{
    zoom_amt = 6;
}
if (distance >= 1600 && distance < 2000)
{
    zoom_amt = 5;
}
if (distance >= 2000)
{
    zoom_amt = 4;
}

$("#map").geomap( "option", "zoom", zoom_amt );

//------------------------actually set center

point-------------------------------

$("#map").geomap( "option", "center", [ centerLat+(distance*.001),

centerLong ] ); // use (distance*.001) to shift the map to the left to account for info bar

//------------------------if user clicks a point, open

gallery------------------------------- $("#map").geomap( { click: function( e, geo ) { var clickResult = $("#map").geomap("find", geo, 12); if (clickResult.length > 0) { var openFirst = 0;

                $.each(clickResult, function () {
                    if (this.type == "Feature")
                {
                    if (openFirst == 0)
                    {
                        var coordsToSplit = this.geometry.coordinates.toString();
                        var splitArray = coordsToSplit.split(",");

                        var Href =

'notepad.php?lat='+splitArray[0]+'&long='+splitArray[1]+'&id='+trail_id;

                        $.fancybox({
                            href: Href,
                            overlayOpacity          : 0.8, // Set opacity to 0.8
                            overlayColor            : "#000000", // Set color to Black
                            padding         : 0,
                            'width'         : 500,
                            'height'            : 580,
                            'autoScale'         : false,
                            'transitionIn'      : 'elastic',
                            'transitionOut'     : 'elastic',
                            'type'          : 'iframe',
                        });
                    }
                    openFirst = 1;
                }
                });
        }
    }
} );

On Mon, Mar 3, 2014 at 12:00 PM, Zac K zsk5386@gmail.com wrote:

Essentially, I'm getting a bunch of GPS points (which works) and trying to draw them, and lines between them, on the map. The first point should use the startTrail service and the last point should use the endTrail service, which each have a little icon to show the start / end of the trip.

On Mon, Mar 3, 2014 at 8:59 AM, Zac K zsk5386@gmail.com wrote:

I'm having some trouble getting this solution to work, probably because I'm not quite sure how to add shapes to the Shapes array. I have used the following code, but the map isn't even showing up, much less the shapes:

// ------------------------------------------------/ // ---------------->>> MAP STUFF <<<---------------/ // ------------------------------------------------*/ //------------------------------------draw items on map-------------------------------------

// set up var numPoints = $('.info_content_row').length; var i = 0;

// needed for drawing lines between points var lastLat = 0; var lastLong = 0;

// create array for geometries var shapes = []; //set up start and end trail images var startTrail = $("#start_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } ); var endTrail = $("#end_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } );

$( ".info_content_row" ).each(function( index ) { var lat = $(this).find('.GPS1').val(); var long = $(this).find('.GPS2').val();

if (i == 0) // start point { // create start point shapes.add({type: "Point", coordinates: [lat, long]}); } else if (i == numPoints-1) // end point { //create end point shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); } else { shapes.add({type: "Point", coordinates: [lat, long]});

//append red line shapes.add({type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]],}, { strokeWidth: "5px" }); }

lastLat = lat; lastLong = long; i++; });

//---------------------------------------set up map------------------------------------------------- var geomCol = { type: 'GeometryCollection', geometries: shapes }; var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); // bbox sets boundaries/zoom/centering

//---------------------------------------set up map-------------------------------------

$("#map").geomap({ zoomMin: 4, bbox: bbox, scroll: "off",

// an array of service objects services: [ { type: "tiled", src: function( view ) { return "http://otile" + ((view.index % 4) + 1) + ". mqcdn.com/tiles/1.0.0/osm/" + view.zoom + "/" + view.tile.column + "/" + view.tile.row + ".png"; } },

      // a service where we draw start trail as CSS markers
      {
        id: "start_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw end trail as CSS markers
      {
        id: "end_trail",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
         id: "lineMark",
        type: "tiled",
        src: ""
      },

      // a service where we draw red marker as CSS markers
      {
        id: "marker",
        type: "tiled",
        src: ""
      }

    ]

});

map.geomap( 'append', geomCol );

On Sat, Mar 1, 2014 at 1:22 PM, Zac K zsk5386@gmail.com wrote:

Thanks a lot! I'm super busy at work the next two weeks but I'll try out your solution asap. I really appreciate it. On Mar 1, 2014 8:37 AM, "Ryan Westphal" notifications@github.com wrote:

Setting the bbox of the map will pick the best zoom level to show that bounding box. An easy way to get the bbox of a bunch of shapes is to add them to a GeometryCollection ( http://geojson.org/geojson-spec.html#geometry-collection ) and then use the $.geo.bbox function ( http://docs.jquerygeo.com/geo/bbox.html).

Assuming the shapes you're appending are already in an array named shapes, you can do something like the following. I recommend calculating the bbox before creating the map so you can set the bbox at the same time as initializing the widget (which avoids requesting unnecessary map tiles). I'm also using $.geo.scaleBy to increase the bbox a little because sometimes the fit is too tight and you miss the edge of some shapes.

// assumed to be an array of the shapes you're addingvar shapes = [ { type: 'Point', coordinates: [ ] }, ... ]; var geomCol = { type: 'GeometryCollection', geometries: shapes};var bbox = $.geo.scaleBy( $.geo.bbox( geomCol ), 2 ); var map = $("#map").geomap({ bbox: bbox}); map.geomap( 'append', geomCol );

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36429224 .

ryanttb commented 10 years ago

I believe I misled you a little when answering your initial question. You don't need a whole GeometryCollection, just a LineString will do for your case (a simple trail). $.geo.bbox works with LineStrings. Here's an example of what I believe you're trying to do but I've left out the CSS markers for simplicity.

http://jsbin.com/qujuz/2/edit

Some notes:

zsk5386 commented 10 years ago

Thank you, Ryan. I'll give this a shot this weekend. If it's helpful, go to www.mytrailapp.com/index.php and click the "see am example" link under "What Is Trail?" (or sign up for an account a login) to see what exactly I'm trying to do. On Mar 5, 2014 5:09 PM, "Ryan Westphal" notifications@github.com wrote:

I believe I misled you a little when answering your initial question. You don't need a whole GeometryCollection, just a LineString will do for your case (a simple trail). $.geo.bbox works with LineStrings. Here's an example of what I believe you're trying to do but I've left out the CSS markers for simplicity.

http://jsbin.com/qujuz/2/edit

Some notes:

  • move service-level shapeStyle changes to end just before appending shapes (because the map doesn't exist yet)
  • use Array.push (Array.add is not a function and shapes is just a simple array)
  • you can use the map itself to put interior points, don't need a fourth service
  • use shingled services to skip some processing when only using graphics
  • adding shapeStyle to the geometries themselves (e.g., {type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]] }, { strokeWidth: "5px" } ) has no effect; shapeStyle must be set when appending the shapes to the map or on a service
  • move line service earlier in the array of services so start/end point services will draw over it

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36806341 .

zsk5386 commented 10 years ago

You'll notice when you put your mouse over a point location on the map, a flag icon comes up. Likewise, if you put your mouse over a point's information (e.g., thumbnails) in the info bar, the flag icon comes up, too. All the relevant code is in the script s_trail.js file about halfway down --- look for the commented header that says MAP. On Mar 5, 2014 5:14 PM, "Zac K" zsk5386@gmail.com wrote:

Thank you, Ryan. I'll give this a shot this weekend. If it's helpful, go to www.mytrailapp.com/index.php and click the "see am example" link under "What Is Trail?" (or sign up for an account a login) to see what exactly I'm trying to do. On Mar 5, 2014 5:09 PM, "Ryan Westphal" notifications@github.com wrote:

I believe I misled you a little when answering your initial question. You don't need a whole GeometryCollection, just a LineString will do for your case (a simple trail). $.geo.bbox works with LineStrings. Here's an example of what I believe you're trying to do but I've left out the CSS markers for simplicity.

http://jsbin.com/qujuz/2/edit

Some notes:

  • move service-level shapeStyle changes to end just before appending shapes (because the map doesn't exist yet)
  • use Array.push (Array.add is not a function and shapes is just a simple array)
  • you can use the map itself to put interior points, don't need a fourth service
  • use shingled services to skip some processing when only using graphics
  • adding shapeStyle to the geometries themselves (e.g., {type: "LineString",coordinates: [[lastLat, lastLong],[lat, long]] }, { strokeWidth: "5px" } ) has no effect; shapeStyle must be set when appending the shapes to the map or on a service
  • move line service earlier in the array of services so start/end point services will draw over it

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36806341 .

ryanttb commented 10 years ago

Very nice looking site! If you're curious, I made a slightly more compact (code-wise) version that does the exact same thing (as my previous example).

http://jsbin.com/zicam/1/edit

It has the following changes:

zsk5386 commented 10 years ago

Hey, thanks so much! I've been trying to implement it and I'm having some problems.

You're going to have to login to see the issues, so I made you an account. Username is "ryan" and password is "12345678". My e-mail address, by the way, is zsk5386@gmail.com. Maybe we can talk more privately/directly via e-mail, as we're probably going to get into some code details I don't necessarily want everyone to see =)

Once you login, click the SAMPLE EURO TRIP trail. The page that comes up has a version of the code you provided implemented. As you can see, the red dots are overlaying the start and end trail images; they should be underneath those images. Likewise, when you put your mouse over some of the content in the info bar (e.g., Venice, Italy) a flag icon comes up, but the flag icon is also behind the red location points instead of on top of it. Thinking of it in terms of z-index, the lines should have the lowest z-index, then the points, then the start/end trail images, then the flag icon should have the highest z-index. But, I can't seem to get these items layered in that fashion.

Also, two other issues arose: (1) when you put your mouse over a point on the map, the flag icon should come up. I got this working with the start and end points, but not any of the middle points. (2) Likewise, when you click on a point on the map, it should open your notepad. I also got this working for the start and end points, but not the middle points. To see what I mean, for example, see the functionality here: http://www.mytrailapp.com/viewtrail.php?id=211 (when you put your mouse over a location point on the map, a flag comes up. if you click the point, it opens the notepad). These two concepts were coded based on the idea that the location points were "Feature" types; but using your code they are no longer "Features," so I'm not sure how to recode this to make it work. I tried using "FeatureCollection" instead of "MultiPoint", but that just caused the whole page to break =(

All guidance appreciated!

On Wed, Mar 5, 2014 at 7:36 PM, Ryan Westphal notifications@github.comwrote:

Very nice looking site! If you're curious, I made a slightly more compact (code-wise) version that does the exact same thing.

http://jsbin.com/zicam/1/edit

It has the following changes:

  • use only a LineString for shape building (don't bother keeping track of start/end/inner points)
  • set shapes' styles as part of the append method (only better in this case because we have one append/service; setting shapeStyle on the service is preferred if you're planning on more than one append call per service)
  • fun trick at the end using Array.slice & a MultiPoint geometry to append the inner trail turn points from the original LineString

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36812590 .

zsk5386 commented 10 years ago

I had to change the code back to the old code because people were using the site and asking me why it wasn't working. But the version of the code that integrates your code with mine that was having the above-mentioned problems is as follows:

// ------------------------------------------------/ // ---------------->>> MAP STUFF <<<---------------/ // ------------------------------------------------*/ //---------------------------------------set up map-------------------------------------

// a LineString for the trail line var trail = { type: 'LineString', coordinates: [] };

$( ".info_content_row" ).each(function( i ) { var lat = $(this).find('.GPS1').val(); var long = $(this).find('.GPS2').val();

// every point goes into the LineString
trail.coordinates.push( [ lat, long ] );

} );

// calculate a nice bounding box before we create the map // to avoid requesting tiles we don't need // scaleBy expands the trail's bbox a little to help geomap choose a nicer zoom level var bbox = $.geo.scaleBy( $.geo.bbox( trail ), 1.5 );

// create a map
var map = $("#map").geomap({

zoomMin: 4, scroll: "off", bbox: bbox,

services: [
  {
    type: "tiled",
    src: function( view ) {
      return "http://otile" + ((view.index % 4) + 1) + ".

mqcdn.com/tiles/1.0.0/osm/" + view.zoom + "/" + view.tile.column + "/" + view.tile.row + ".png"; } },

  // a service where we draw red line
  {
    id: "lineMark",
    type: "shingled",
    src: ""
  },

  // a service where we draw start trail as CSS markers
  {
    id: "start_trail",
    type: "shingled",
    src: ""
  },

  // a service where we draw end trail as CSS markers
  {
    id: "end_trail",
    type: "shingled",
    src: ""
  },

  // a service where we draw red marker as CSS markers
   {
      id: "marker",
      type: "shingled",
      src: ""
  }
],

// only applies to interior trail points
// because that's all we put on the map widget itself
shapeStyle: {
  fillOpacity: 1,
  strokeWidth: 9
}

});

map.geomap( "append", { type: "Feature", geometry: { type: "MultiPoint", coordinates: trail.coordinates } } );

// set shapeStyles & append shapes // note the trailing false on all append calls // except for the last to avoid unnecessary refreshes

// set start point shapeStyle & append Point var startTrail = $("#start_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } ); startTrail.geomap( "append", { type: "Feature", geometry: { type: "Point", coordinates: trail.coordinates[ 0 ] } }, "" );

// set end point shapeStyle & append Point var endTrail = $("#end_trail").geomap( "option", "shapeStyle", { width: 0, height: 0 } ); endTrail.geomap( 'append', { type: "Feature", geometry: { type: 'Point', coordinates: trail.coordinates[ trail.coordinates.length - 1 ] } }, "" );

// set trail line shapeStyle & append LineString $( '#lineMark' ).geomap( 'append', trail, { strokeWidth: 5 } );

//------------------------if user clicks a point, open gallery------------------------------- $("#map").geomap( { click: function( e, geo ) { var clickResult = $("#map").geomap("find", geo, 12); if (clickResult.length > 0) { var openFirst = 0;

    $.each(clickResult, function () {

alert(this.type); if (this.type == "Feature") { if (openFirst == 0) { var coordsToSplit = this.geometry.coordinates.toString(); var splitArray = coordsToSplit.split(",");

var Href = 'notepad.php?lat='+splitArray[0]+'&long='+splitArray[1]+'&id='+trail_id;

$.fancybox({ href: Href, overlayOpacity : 0.8, // Set opacity to 0.8 overlayColor : "#000000", // Set color to Black padding : 0, 'width' : 500, 'height' : 580, 'autoScale' : false, 'transitionIn' : 'elastic', 'transitionOut' : 'elastic', 'type' : 'iframe', }); } openFirst = 1; } }); } } } );

//------------------------on mouse over point put flag icon------------------------------- var pointSet = 0; var coordsToSplit = ""; var splitArray = []; var splitGeo = []; var cntNum = 0;

$("#map").geomap( { move: function( e, geo ) { var moveResult = $("#map").geomap("find", geo, 12);

if (moveResult.length > 0) { splitGeo = geo.coordinates.toString().split(","); cntNum = 0;

    $.each(moveResult, function ()

{ if (this.type == "Feature") { coordsToSplit = this.geometry.coordinates.toString(); splitArray = coordsToSplit.split(",");

if (pointSet == 0) { // add marker to point marker.geomap( "append", { type: "Point", coordinates: [ splitArray[0], splitArray[1] ] }, "" );

pointSet = 1; }

} else { if (pointSet == 1) { if (cntNum < 1) { marker.geomap("empty"); // remove marker if move mouse away from point pointSet = 0; } } } cntNum++; }); } else { if (pointSet == 1) { marker.geomap("empty"); // remove marker if move mouse away from point } pointSet = 0; } } } );

//-----------------on-mouse-over location makes background gray and point on map------------------------

var marker = $("#marker").geomap( "option", "shapeStyle", { width: 0, height: 0 } );

$('.info_content_row').mouseenter(function() { $( this ).children().css('background-color','#f1ebeb');

var GPSlocation1 = $(this).find('.GPS1').val(); // get GPS location from hidden input box var GPSlocation2 = $(this).find('.GPS2').val(); // get GPS location from hidden input box

marker.geomap( "append", { type: "Point", coordinates: [ GPSlocation1, GPSlocation2 ] }, "" );

});

$('.info_content_row').mouseleave(function() { $( this ).children().css('background-color','white');

marker.geomap("empty"); });

On Fri, Mar 7, 2014 at 8:03 PM, Zac K zsk5386@gmail.com wrote:

Hey, thanks so much! I've been trying to implement it and I'm having some problems.

You're going to have to login to see the issues, so I made you an account. Username is "ryan" and password is "12345678". My e-mail address, by the way, is zsk5386@gmail.com. Maybe we can talk more privately/directly via e-mail, as we're probably going to get into some code details I don't necessarily want everyone to see =)

Once you login, click the SAMPLE EURO TRIP trail. The page that comes up has a version of the code you provided implemented. As you can see, the red dots are overlaying the start and end trail images; they should be underneath those images. Likewise, when you put your mouse over some of the content in the info bar (e.g., Venice, Italy) a flag icon comes up, but the flag icon is also behind the red location points instead of on top of it. Thinking of it in terms of z-index, the lines should have the lowest z-index, then the points, then the start/end trail images, then the flag icon should have the highest z-index. But, I can't seem to get these items layered in that fashion.

Also, when you put your mouse over a point on the map, the flag icon should come up (I got this working with the start and end points, but not any of the middle points). When you click on a point on the map, it should open your notepad (I also got this working for the start and end points, but not the middle points. See, e.g., the functionality here: http://www.mytrailapp.com/viewtrail.php?id=211 --> when you put your mouse over a point on the map, a flag comes up. if you click the point, it opens the notepad). These two features were based on the idea that the point types were "Features"; but using your code they are no longer "Features," so I'm not sure how to recode this to make it work.

All guidance appreciated!

On Wed, Mar 5, 2014 at 7:36 PM, Ryan Westphal notifications@github.comwrote:

Very nice looking site! If you're curious, I made a slightly more compact (code-wise) version that does the exact same thing.

http://jsbin.com/zicam/1/edit

It has the following changes:

  • use only a LineString for shape building (don't bother keeping track of start/end/inner points)
  • set shapes' styles as part of the append method (only better in this case because we have one append/service; setting shapeStyle on the service is preferred if you're planning on more than one append call per service)
  • fun trick at the end using Array.slice & a MultiPoint geometry to append the inner trail turn points from the original LineString

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-36812590 .

ryanttb commented 10 years ago

I am sorry I missed the window. Is it possible to host a development version on another URL/server?

Regarding the z-index issue, you are right, I did make my sample too simple for your needs. Here are some starting points:

ryanttb commented 10 years ago

Sorry I missed the window. You are right, a led you astray by oversimplifying my example. Are you able to put up a development version at a different URL? Regardless, here are some thoughts:

Let me know if any of this helps and I will work on an example better suited to your specific needs.

zsk5386 commented 10 years ago

No problem! I appreciate all your help!

I put the development version of the code at http://mytrailapp.com/js/scripts_trail2.js. To see it in action, login to your trail account and go to http://mytrailapp.com/trail2.php?id=245 ... trail2.php uses scripts_trail2.js. As we discuss code changes I'll try to make them to that file so you can see the changes reflected in a working version.

On Wed, Mar 12, 2014 at 8:08 PM, Ryan Westphal notifications@github.comwrote:

Sorry I missed the window. You are right, a led you astray by oversimplifying my example. Are you able to put up a development version at a different URL? Regardless, here are some thoughts:

  • the z-index you speak of is entirely controlled by the order of objects in the services array, with the caveat that shapes appended to the map itself will show over everything
  • since I suggested putting the middle dots on the map, they will appear on top of anything in your marker service or any other service
  • despite what I said before, it seems you do want a new service for the mid-points and, as you say, your 'move' & 'click' code clearly requires a Feature object so instead of appending a single MultiPoint as I suggested, you should go back to iterating through them and creating Feature objects instead.

Let me know if any of this helps and I will work on an example better suited to your specific needs.

Reply to this email directly or view it on GitHubhttps://github.com/AppGeo/geo/issues/153#issuecomment-37484755 .