none
Richard's polygon search code... works great the first time, but if I "save" the polygon and search it later the search isn't right. RRS feed

  • Question

  • Hi,

     

    Thanks to Richard's polygon search code, I have been able to add that functionality to my project. The user creates a polygon and clicks search. All pins within that polygon are displayed, and any pins outside are hidden. I print output telling the user the number of pins displayed.

    In addition to this basic functionality, I "save" the polygons the user creates using a click event to add a DOM element to the page (a link the user can click on to redraw the polygon and display the pins inside it). This code is as follows:

     

     

    Event.add(area_el, 'click', function(e)
       {
        polyPoints = [];
        var thePolyPoints = (created_area_array[new_entry_array_index]).toString();
        
        //formatting created_area_array[new_entry_array_index] to store as polygon points in the polyPoints array
        thePolyPoints = thePolyPoints.replace(/[\[\]{}]/g, "");
        thePolyPoints = thePolyPoints.replace(/Location/g, "");
        
        //adding the co-ordinates to the polyPoints array
        thePolyPoints = thePolyPoints.split(",");  
        for(var ctr=0; ctr+1<thePolyPoints.length; ctr+=2)
        {
         var location1 = new Microsoft.Maps.Location(thePolyPoints[ctr],thePolyPoints[ctr+1]);
         polyPoints.push(location1);
        }
        
        //creating the polygon and searching...
        if(create_area==true)
        {
         drawPolygon(); 
         setTimeout("polygonSearch()", 500); 
        }
        else if(create_area==false)
        {
         document.getElementById('createarea').innerHTML = "<a id='createarea'><span class='create_area' style='color:blue'><strong>Create Area</strong></span></a>";
         document.getElementById("mapDiv").oncontextmenu = function(){return false}
         MouseUpHandlerId = Microsoft.Maps.Events.addHandler(map, "mouseup",MouseUpHandler);
         MouseDownHandlerId = Microsoft.Maps.Events.addHandler(map, "mousedown",MouseDownHandler);
         MouseMoveHandlerId = Microsoft.Maps.Events.addHandler(map, "mousemove",MouseMoveHandler);
         MouseOverHandlerId = Microsoft.Maps.Events.addHandler(map, "mouseover",MouseOverHandler);
         drawPolygon(); 
         setTimeout("polygonSearch()", 500);
         create_area=true;
        }   
       });
    

     


    So the polygon gets created where it should, but polygonSearch does not detect all the pins it should, or sometimes it detects too many, and displays them outside the polygon. I don't understand why the search function works the first time, but the "saved" polygon doesn't work. It maybe has something to do with how I'm storing it - I end up parsing a string, so maybe the thing I operate on is a string rather than a float - but the output seems to show a numeric value with the proper precision, so I'm at a loss.

    The polygonSearch bit to determine if the pin is within the polygon is as follows ('points' being the polyPoints array):

     

    function pointInPolygon(points,lat,lon)
    {
     var i;
     var j=points.length-1;
     var inPoly=false;
     for (i=0; i<points.length; i++)
     {
      if (points[i].longitude<lon && points[j].longitude>=lon || points[j].longitude<lon && points[i].longitude>=lon)
      {
       var temp = parseFloat(points[i].latitude+(lon-points[i].longitude)/(points[j].longitude-points[i].longitude)*(points[j].latitude-points[i].latitude));
       if (temp<lat)
        inPoly=!inPoly;
      }
      j=i;
     }
     return inPoly;
    }
    
    


     

    If anyone has an idea, I'm all ears. Thanks for reading!


    • Moved by Ricky_Brundritt Saturday, March 10, 2012 10:26 AM (From:Bing Maps: Map Control and Web services Development)
    Monday, August 1, 2011 8:10 AM

Answers

  • In the line of code:

    var location1 = new Microsoft.Maps.Location(thePolyPoints[ctr],thePolyPoints[ctr+1]);

    try parsing the string input for the coordinates using parseFloat


    http://rbrundritt.wordpress.com
    • Marked as answer by kevin-berry Thursday, August 4, 2011 5:47 AM
    Thursday, August 4, 2011 12:08 AM

All replies

  • Can you provide information on how you are saving the polygon? This is likely the issue. If you add extra points at the end of the polygon, even if they are the same point then the algorithm could return unexpected results.
    http://rbrundritt.wordpress.com
    Tuesday, August 2, 2011 6:33 PM
  • Well, what you see there with the Even.add function is how I save it.

     

    I have an array of the areas:

    var created_area_array = Array();

    If I am adding a new shape, I store the polyPoints:

    var new_entry = polyPoints;

    I then push this new entry onto the array:

    created_area_array[new_entry_array_index] = new_entry;

    The new entry ends up as a <span> element on the page that the user can click to bring up the polygon. This next code is what happens when the user clicks the text of the new entry I created. The polygon looks right on the page, but as you said, there could be unexpected results.

     Event.add(area_el, 'click', function(e)
     {
      if(!currently_renaming)
      {
       polyPoints = [];
       var thePolyPoints = (created_area_array[new_entry_array_index]).toString();
       
       //formatting created_area_array[new_entry_array_index] to store as polygon points in the polyPoints array
       thePolyPoints = thePolyPoints.replace(/[\[\]{}]/g, "");
       thePolyPoints = thePolyPoints.replace(/Location/g, "");
       
       //adding the co-ordinates to the polyPoints array
       thePolyPoints = thePolyPoints.split(",");  
       for(var ctr=0; ctr+1<thePolyPoints.length; ctr+=2)
       {
        var location1 = new Microsoft.Maps.Location(thePolyPoints[ctr],thePolyPoints[ctr+1]);
        polyPoints.push(location1);
       }
       
       //creating the polygon and searching...
       if(create_area==true)
       {
        drawPolygon(); 
        polygonSearch();
       }<br/>...... <br/>
    

     

    Some output... for a 3-point *closed* polygon, after

    var thePolyPoints = (created_area_array[new_entry_array_index]).toString();
    

    alert(thePolyPoints) gives me...

    [Location 49.1882808800459,-123.77078552246095],
    [Location 49.091250586396114,-124.10724182128908],
    [Location 49.038163048234765,-123.90124816894533],
    [Location 49.1882808800459,-123.77078552246095]

    Once I split it and push the individual lat/long to polyPoints, this is what polyPoints contains (after looping through polyPoints[i]):

    [Location  49.1882808800459,-123.77078552246095]
    [Location  49.091250586396114,-124.10724182128908]
    [Location  49.038163048234765,-123.90124816894533]
    [Location  49.1882808800459,-123.77078552246095]

     

     

    Here's the full code in case it's helpful (the renaming functionality is a work in progress).

     

    var created_area_array = Array();
    var createdarea_index = 0;
    var number_of_areas_saved=0;
    var currently_renaming=false;
     
    Event.add(window, 'load', function()
    {
     Event.add('SubmitArea', 'click', function()
     {
      if(polyPoints.length>0)
       add_created_area();
     }); 
    });
    
    function add_created_area()
    {
     number_of_areas_saved++;
     var area_el = document.createElement('span');
     var area_el_remove = document.createElement('span');
     area_el_rename = document.createElement('span');
     var new_entry = polyPoints;
     var new_entry_array_index = "Area" + (createdarea_index);
     var new_entry_array_name = "Area #" + (createdarea_index+1);
     area_el.innerHTML = '<span class=\"address-text\">' + new_entry_array_name + '</span><br>';
     
     area_el_remove.innerHTML = "<a onMouseOver=\"rollover('address_remove')\" onMouseOut=\"rollout('address_remove')\" style='cursor:pointer;'>" +
     "<img src=\"images/tabs-icons/normal-address_remove.png\" name='address_remove' title='remove' alt='remove'></a>&nbsp;";
     
     area_el_rename.innerHTML = "<a onMouseOver=\"rollover('area_rename')\" onMouseOut=\"rollout('area_rename')\" style='cursor:pointer;'>" +
     "<img src=\"images/tabs-icons/normal-area_rename.png\" name='area_rename' title='rename' alt='rename'></a>&nbsp;";
     
     created_area_array[new_entry_array_index] = new_entry;
     createdarea_index++;
     
     Dom.add(area_el_remove, 'CreatedAreas');
     Dom.add(area_el_rename, 'CreatedAreas');
     Dom.add(area_el, 'CreatedAreas');
     Event.add(area_el, 'click', function(e)
     {
      if(!currently_renaming)
      {
       polyPoints = [];
       var thePolyPoints = (created_area_array[new_entry_array_index]).toString();
       
       //formatting created_area_array[new_entry_array_index] to store as polygon points in the polyPoints array
       thePolyPoints = thePolyPoints.replace(/[\[\]{}]/g, "");
       thePolyPoints = thePolyPoints.replace(/Location/g, "");
       
       //adding the co-ordinates to the polyPoints array
       thePolyPoints = thePolyPoints.split(",");  
       for(var ctr=0; ctr+1<thePolyPoints.length; ctr+=2)
       {
        var location1 = new Microsoft.Maps.Location(thePolyPoints[ctr],thePolyPoints[ctr+1]);
        polyPoints.push(location1);
       }
       
       //creating the polygon and searching...
       if(create_area==true)
       {
        drawPolygon(); 
        polygonSearch();
       }
       else if(create_area==false)
       {
        document.getElementById('createarea').innerHTML = "<a id='createarea'><span class='create_area' style='color:blue'><strong>Create Area</strong></span></a>";
        document.getElementById("mapDiv").oncontextmenu = function(){return false}
        MouseUpHandlerId = Microsoft.Maps.Events.addHandler(map, "mouseup",MouseUpHandler);
        MouseDownHandlerId = Microsoft.Maps.Events.addHandler(map, "mousedown",MouseDownHandler);
        MouseMoveHandlerId = Microsoft.Maps.Events.addHandler(map, "mousemove",MouseMoveHandler);
        MouseOverHandlerId = Microsoft.Maps.Events.addHandler(map, "mouseover",MouseOverHandler);
        drawPolygon(); 
        polygonSearch();
        create_area=true;
       }   
      }
     });
     Event.add(area_el_remove, 'click', function(e)
     {
      Dom.remove(this);
      Dom.remove(area_el_rename);
      Dom.remove(area_el);
      if(number_of_areas_saved>1)
       number_of_areas_saved--;
     });
     /*Event.add(area_el_rename, 'click', function(e)
     {
      if(!currently_renaming)
      {
       area_el.innerHTML = '<textarea name=\"renaming_area\" id=\"renaming_area\" style=\"width:200px;height:10px;background-color:#DCDCDC; resize:none;font-size:8px;\" onKeyPress=\"return enter_rename(area_el, event)\" maxlength=\"30\"></textarea><br>';
       currently_renaming=true;
      }
     });*/
     Event.add("createdarea_clear", 'click', function(e)
     {
      Dom.remove(area_el_remove);
      Dom.remove(area_el_rename);
      Dom.remove(area_el);
      created_area_array = [];
      number_of_areas_saved=0;
      createdarea_index=0;
     });
    }
    
    

     

     


    Tuesday, August 2, 2011 7:17 PM
  • In the line of code:

    var location1 = new Microsoft.Maps.Location(thePolyPoints[ctr],thePolyPoints[ctr+1]);

    try parsing the string input for the coordinates using parseFloat


    http://rbrundritt.wordpress.com
    • Marked as answer by kevin-berry Thursday, August 4, 2011 5:47 AM
    Thursday, August 4, 2011 12:08 AM
  • That did the trick! Thanks! :)
    Thursday, August 4, 2011 5:47 AM