Changing the path of a polyline through code manipulation can sometimes result in a lingering phantom line

Users can edit lines on the map by dragging their vertices. When a vertex is moved, the system checks if it is near another object and attaches the line to that object if necessary.

During this process, when the user moves the line, the "set_at" event is triggered. In the function called by the listener, the line is programmatically edited to attach itself to the nearest object, if one exists. The original line remains visible but translucent on the map. However, this line eventually disappears after other operations are performed on the map.

Attempts have been made to clear the path (path.clear()), create a new path, remove it from the map (setMap(null)), and place it again (setMap(LocationPicker.map.map)). Unfortunately, none of these solutions have proven successful.

google.maps.event.addListener(marker.getPath(), 'set_at', function(vertex, eventC) {
    LocationPicker.controlVertexMovement(marker,vertex, eventC);
});

controlVertexMovement: function(marker, vertex, eventC) {
    var path = marker.getPath();
    var closest = LocationPicker.searchClosestObject(path.j[vertex].lat(), path.j[vertex].lng());
    if(closest!=null){
        path.j[vertex] = closest.latlng;
        LocationPicker.map.overlays[overlayNum].setPath(path);
    }
}

The current result can be seen here: The expected result should look like this:

For a working example, check out this example fiddle.

Code Snippet:

 ... (Omitted for brevity) ... 
/* Styles omitted for brevity */
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_HERE"></script>

Answer №1

path.j is not a well-documented property. Avoid using undocumented properties as they can change with each API release. Stick to using only documented properties and methods.

Avoid:

path.j[vertex] = new google.maps.LatLng(-34.397, 150.644);

An alternative approach is to use:

path.setAt(vertex,new google.maps.LatLng(-34.397, 150.644));

Here's an example:

google.maps.event.addListenerOnce(flightPath.getPath(), 'set_at', processSetAt);

function processSetAt(vertex, eventC) {
  // Disable editing
  flightPath.setEditable(false);
  // Update the path
  var path = flightPath.getPath();
  path.setAt(vertex,new google.maps.LatLng(-34.397, 150.644));
  flightPath.setPath(path);
  // Re-enable editing
  flightPath.setEditable(true);
  google.maps.event.addListenerOnce(flightPath.getPath(), 'set_at', processSetAt);
} 

See proof of concept fiddle

Note that your issue appears to be related to modifying the path of the polyline while it is in "editable" mode. The workaround I found was to disable editing, make the modifications, then re-enable editing to avoid any "ghost" paths.

Another option (suggested by OP):

Use a flag to prevent an infinite loop on the 'set at' event. Here's how:

google.maps.event.addListener(flightPath.getPath(), 'set_at', function(vertex, eventC) { 
  if(!changingPath){ 
    var path = flightPath.getPath(); 
    changingPath = true; 
    path.setAt(vertex, new google.maps.LatLng(-34.397, 150.644)); 
    changingPath = false; 
  } 
}); 

fiddle

Code snippet:

function initialize() {
  // Map settings
}

/**
 * A menu that lets a user delete a selected vertex of a path.
 * @constructor
 */
function DeleteMenu() {
  // Menu functionality
}
DeleteMenu.prototype = new google.maps.OverlayView();

// More DeleteMenu functions

google.maps.event.addDomListener(window, 'load', initialize);
#map {
  height: 100%;
}

html,
body {
  // Styling
}

.delete-menu {
  // Menu CSS
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

assign the value of a select box using a function

I have a data table with rows containing date input boxes using Jquery datepicker, and a column in the table has a dropdown box with Yes and No values. When a date input box is selected with a value, I want to automatically prepopulate the dropdown with Ye ...

Managing and displaying information provided through forms

I'm currently developing a URL shortening tool, but I'm encountering difficulties in extracting jQuery form values to generate the shortened URL text. You can view the form layout here: <form name="urlForm"> <input type="text" name ...

Refreshing data in Laravel after an AJAX request

Currently, he is working on coding that involves filtering data within a table. Using Ajax to call the link will retrieve a response (json) with the answers. However, there has been an issue. The task at hand is to render tables without using append or sim ...

Javascript will not recognize or interpret PHP's HTML tags

When PHP sends HTML strings to HTML through AJAX wrapped in <p class="select"></p> tags, the CSS reads the class perfectly. However, JavaScript/jQuery does not seem to work as expected. Even when trying to parse <p onclick="function()">&l ...

Establishing the Access-Control-Allow-Origin

I have a basic .NET web service: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; /// <summary> /// Summary description for WebService /// </summary> [WebService(Namespace = "http ...

Problem with updating an Html.TextBoxFor based on the value of another one

I have been trying to implement a basic jQuery functionality that involves changing the text in one textbox to be half of the numeric value entered in another textbox. Below is the script I am using: <script> $(document).ready(function () { $(& ...

Regular Expression - Locate all numerical values within text formatted with HTML

I am attempting to locate all the numbers within an HTML document. However, I want to ensure that I exclude numbers that are part of a word, such as "o365", "high5", and similar instances. Here is my current approach, but it does not successfully avoid w ...

Ways to convert a callback-based function into a promise without losing the returned value

After being given access to this API: function doSomeWork(callbacks : { success ?: (result : SuccessCallbackResult) => void, fail ?: (result : FailCallbackResult) => void, complete ?: (result : CompleteCallbackResult) => void }) : Task ...

Issue with ngTable: Error retrieving data for server-side pagination

I am currently working on setting up a server-side table using ng-table. However, I am encountering some issues with the getData function. It keeps giving me errors such as $defer.resolve is not a function or params is not defined. I noticed that I can ac ...

Leveraging CSS or JavaScript for Displaying or Concealing Vacant Content Sections

I'm working on developing a page template that utilizes section headers and dynamically pulled content from a separate database. The current setup of the page resembles the following structure: <tr> <td> <h3> ...

What methods can I use to identify if the browser my users are using does not have support for Bootstrap 4?

My recent project heavily utilizes the advanced features of Bootstrap 4/CSS, making it incompatible with older browsers still in use by some of my visitors. How can I effectively identify when a user's browser does not support bootstrap 4 so that I c ...

When no values are passed to props in Vue.js, set them to empty

So I have a discount interface set up like this: export interface Discount { id: number name: string type: string } In my Vue.js app, I am using it on my prop in the following way: export default class DiscountsEdit extends Vue { @Prop({ d ...

Utilize AJAX, jQuery, and Symfony2 to showcase array information in a visually appealing table format

I have a requirement to showcase data utilizing ajax and jQuery in a table on my twig file. The ajax call is made with a post request to the controller, where the controller attempts to input several rows from a csv file into the database. However, there ...

Can you explain the distinction between browser.sleep() and browser.wait() functions?

Encountering timing problems with my protractor tests. Occasionally, test cases fail because of network or performance-related issues. I managed to resolve these issues using browser.sleep(), but recently discovered browser.wait(). What sets them apart an ...

Please provide a validation error message when attempting to select a dropdown list while the checkbox is unchecked

There are 7 drop down menus in a table row. When trying to select a value from the drop downs with the checkbox unchecked, a validation message should be displayed saying "Please enable the checkbox". If the checkbox is checked, all the drop down menus sh ...

Mastering the art of utilizing class attributes and functions from within modules

Currently, I am developing classes in ES6 modules using object literals and my intention is to update object attributes within a function. Although modules run in strict mode by default which ensures safe usage of this, I am uncertain whether calling the ...

What is the best way to fetch and convert information from an API to display on a website?

I am encountering an issue while trying to retrieve data from an API. Below is my code with a fabricated access code. $(function () { var $data = ('#data'); $.ajax({ type: 'GET', url: 'http://api.openweathe ...

Tips for presenting JSON data retrieved using jQueryWould you like to know how

Is there a way to extract and display the user id from JSON values? I'm trying to access the user id value. $('User_id').observe('blur', function(e) { var txt = $('User_id').value; jQuery.ajax({ type: 'g ...

Using the Proper 'this' Reference Without Repeating 'this' in Nested Functions

I am facing an issue in my class where I have multiple methods and properties. One of these methods contains a setTimeout() function as follows: function myClass() { this.some_property = "test"; this.PrintOnTimeout = function() { // I thou ...

Is there a way to insert a row into a datatable without needing to perform an Ajax reload or using the

When using row.add(…) on a datatable, I encounter an issue where it refreshes via an ajax call when draw() is activated. This leads to the new row not being visible because the data is reloaded from the database. The UX flow behind this scenario is as f ...