We're using Drupal 5.7, somewhat customized versions of Location 1.x-dev + GMap 1.0-beta2 to display a list of volunteer opportunities on www.urbanministry.org - for example, http://www.urbanministry.org/volunteer/mapopportunities?op0=25&filter0=0....

We're using the views theme plugin code from #123601: Combine a gmap and any other views plugin to get the data to display in a table below the Gmap, also. However, not all of the nodes that show up with a valid Google Maps link in the table show up on the Google Map at the top of the page.

Does anyone know why some nodes would not have markers? Also, does the Gmap module use Google's own system for locating places based on their address, or does it simply use the latitudes/longitudes provided by the Location module? If it is the latter, is there any way to modify it to use Google's system (i.e., like how when you type an address into the Google Maps & it locates it for you?)

Comments

EvanDonovan’s picture

Title: GMap Views not showing markers for all nodes w/valid Google Maps » GMap Views not showing distinct markers for nodes in same zip code w/different addresses
Category: support » bug

I have determined, by creating a simpler test view (http://www.urbanministry.org/oppmap2?op0=25&filter0=02122&filter1=**ALL**) what the issues were:

1) The GMap does not show more than one node that has the same lat/long information. In this case, it only shows the first volunteer opportunity listed.

2) The GMap does not show more than one node that has the same zipcode.

3) When using autozoom, markers can appear just slightly off the edge of the map. I believe I read an issue with a patch for that a while back, but I seem to have forgotten its #. Maybe someone can help? :)

Issues #1 & 2 are the really critical ones for our site's map functionality.

#1 may be more of a feature request (make it possible to have a marker pop-up that has links to multiple nodes at the same lat/long).

#2, however, is a definite bug, in my opinion. The different opportunities may share the same zipcode, but they should have different lat/long since they have different addresses. They should have different markers, even if they are very close together.

Thanks bdragon & all for your continued work on this invaluable module!

EvanDonovan’s picture

Here's what I'd like to do to get these issues resolved. Maybe someone can advise on how to do it?

For #1: Make it so that the marker popups have links to the different volunteer opportunities nodes if they are at the same address. Thus, clicking on one marker would show all the nodes at that address.

Could a theming function do this? (Some sort of condition checking on the address + iterating over the array of node links to put them in a comma separated list in the marker popup.)

For #2: Make it possible to differentiate the addresses by using zip+4 or something.

Could the Location module do a lookup & rewrite the addresses to use zip+4? Also, is it possible to do a mass update of location data (through admin/content/node, for example)?

tom_o_t’s picture

I'd suggest splitting up your node (content) types - one for location, and one for volunteer opportunity. Link the volunteer opp. to the location using a nodereference field.

So a community center is one node with an address, which shows up on the map.
Clicking on it shows the popup infowindow, which lists all opportunities at the location, each of which is a link to the full details of the opportunity.

If you hunt around in the issue queue you'll find a guide to theming the info window - basically you create a tpl.php file for the info window and create a new function in template.php

EvanDonovan’s picture

Thanks, tom_o_t, for the suggestion! Sounds like it would be an excellent way to work, if we had designed the database tables that way in the first place. Unfortunately, since we did an import from another system, it might be harder to implement.

My own ability to work on the site doesn't go below the presentation layer, so I don't know if I'd be able to modify the database to create the proper nodereference fields in the CCK opportunities nodetype. We have thousands of organizations, and I think we would have to run SQL queries on our old database (christianvolunteering.org) to find out what the opp_id numbers were for the opportunities associated with each. Then we'd have to create some kind of mapping.

I'll look into the theming function for now, since that's at least something that I have some knowledge of. Maybe eventually our database person will be free, so that she can get the organization & opportunities nodetypes more closely linked :)

EvanDonovan’s picture

Title: GMap Views not showing distinct markers for nodes in same zip code w/different addresses » GMap Views able to show distinct markers or links for places w/same lat/long?
Category: bug » feature

As I described in reply #1 to my issue #284501: Increase Accuracy, Robustness of Geolocation when using Location lat/long + GMap Views, after updating the geolocation data for the nodes on our site, we are showing more than one marker per zipcode.

However, we still are only able to see one volunteer opportunity per organization, since the volunteer opportunities for an organization have the same latitude & longitude. We would have to do an extensive reworking of our data to implement the nodereference field suggestion that tom_o_t offered. I will look into other alternatives, such as getting more than one node link into a marker popup (via a theming function).

Just wanted to update this issue to state that it's not a bug b/c it makes sense normally for only one marker to show up per latitude/longitude.

kkrgopalan’s picture

I would like to know if showing multiple markers at the same lat long is possible at this point. The way I see google maps doing this is by clicking on the marker cause you to cycle through the markers at the same location. Does this functionality currently exist in the gmap module?

dan.crouthamel’s picture

I'm interested in this as well, but in the 6.x version.

dan.crouthamel’s picture

StatusFileSize
new26.47 KB

I don't know if anyone would have a use for this, but what I did was modify the code and placed multiple marker locations around the same lat/long. For example, suppose I had 10 markers with the same location, it would only appear with one marker node on the location map.

x

Now it appears like this,

x
x x x
x x x
x x x

The separation between 2 x's (in x and y direction) is .00003. See attached pic.

Now this has flaws itself as I don't check to see if a marker is already present where I'm placing a new one, but that really isn't going to be the case for me and what I'm using this for :)

sjf’s picture

My use case: I have lots of group posts on a map, all using the lat/long from their parent organic groups, meaning lots of posts from the same group all with identical coordinates. Clusterer seemed like the solution but it's broken for 6.x. gmap_views so dan, this is exactly what I'm looking for! Please share the code :)

dan.crouthamel’s picture

StatusFileSize
new7.57 KB
new28.46 KB

Hmm, I haven't heard of Clusterer - I'll have to check that out :)

Below are the 2 sections I added to each attached file (gmap_plugin_style_gmap.inc and gmap_location.module), although they are a bit different in each file. See attached files. In gmap_location.module I only updated the gmap_location_node_page function. I'm not using user locations, but you can do the same thing in gmap_location_user_page if needed. You might need to tweak the $offSet value, depending on what marker you are using and its size.

Note - this does not change the lat/long value in the database, it just changes what lat/long is used for display. If anyone sees anything completely wrong or something that can be made more efficient please let me know.

  // *dan.crouthamel++
	$multiLocs = array();
	$offSet = .00003;  //spacing in the X and Y direction for each new marker
	$curVal = 0;  //current duplicate value of lat/long combination - 1
	$magVal = 0;  //number of steps from origin to current "square" wall being built
	$stepVal = 0;  //number of steps from start position of current "square" wall being built.
	               //In northern hemisphere, this starts at the upper right; southern hemisphere, lower right ... I think that's right :)
	$numSteps = 0;  //magVal * 2
	$dirVal = 0;  //0, 1, 2, or 3 - represents current direction of the square being built (see cases below)
	$posVal = 0;  //current position value along a "square" wall being built, resets to zero when dirVal changes (new segment of square being built)
	// *dan.crouthamel--
		// *dan.crouthamel++
		$multiLocs[$newmarker['latitude']][$newmarker['longitude']] += 1;
		
		if ($multiLocs[$newmarker['latitude']][$newmarker['longitude']] > 1)
		{
			$curVal = $multiLocs[$newmarker['latitude']][$newmarker['longitude']] - 1;
			$magVal = (int) ((sqrt($curVal)+1)/2);
			$stepVal = $curVal - pow(2*$magVal-1,2);
			$numSteps = 2*$magVal;
			$dirVal = (int) ($stepVal / $numSteps);
			$posVal = $stepVal % $numSteps;
			
			switch ($dirVal) {
				//Top to bottom
				//       x
				// x x x |
				// x x x |
				// x x x |				
				case 0:
					$newmarker['longitude'] += ($magVal*$offSet);
					$newmarker['latitude'] += $offSet*($magVal - $posVal);
					break;
					
				//Right to left
				//       x
				// x x x x
				// x x x x
				// x x x x
				// - - - x				
				case 1:
					$newmarker['latitude'] -= ($magVal*$offSet);
					$newmarker['longitude'] += $offSet*($magVal - $posVal);
					break;
					
				//Bottom to top
				//         x
				// | x x x x
				// | x x x x
				// | x x x x
				// x x x x x					
				case 2:
					$newmarker['longitude'] -= ($magVal*$offSet);
					$newmarker['latitude'] += $offSet*($posVal - $magVal);
					break;
					
				//Left to right
				// x - - - x
				// x x x x x
				// x x x x x
				// x x x x x
				// x x x x x						
				case 3:
					$newmarker['latitude'] += ($magVal*$offSet);
					$newmarker['longitude'] += $offSet*($posVal - $magVal);
					break;
			}
		}	
		// *dan.crouthamel--
sjf’s picture

I tried this and it works brilliantly. I'll incorporate slightly transparent markers, and the click-to-zoom clusterer modification. Thanks dan!

dan.crouthamel’s picture

Glad it worked for you. I finally found the clusterer option. I guess I should pay more attention to what is actually available in the admin settings :)

drupal_bineec’s picture

Hi,
I copied the same code for my results to be displayed and it did not show multiple markers. any advice?

dan.crouthamel’s picture

On which map are you trying to show multiple markers. Location map, user location map, or in a view?

drupal_bineec’s picture

node map,

dan.crouthamel’s picture

Can's say for sure what's happening. I'd have to take a look a the file you updated. Also, I should mention that the updates I made where agains the 6.x version of Gmap, not 5.x.

drupal_bineec’s picture

Yes I am using the 6.x version of gmap. The only change in my code is the sql change. I have 5 nodes with same loc and one with different so I see only 2 markers. The gmap configuration for marker manager is Google's GMarker manager, am I missing some thing.
Here is my code

$nodemap = variable_get('gmap_node_map', _gmap_location_node_map_defaults());
      $markertypes = variable_get('gmap_node_markers', array());
    
      $map = array_merge(
        gmap_defaults(),
        gmap_parse_macro($nodemap['macro']));
    
      $mode = $nodemap['markermode'];
      $map['rmtcallback'] = url('map/node/load');
      $map['markermode'] = $nodemap['markermode'];
    
      if (!isset($map['markers']) || !is_array($map['markers'])) {
        $map['markers'] = array();
      }
              
      $result = db_query(db_rewrite_sql("
        SELECT n.nid, n.type, n.title,z.latitude, z.longitude 
        FROM {node} n , {users} u, {user_address} a, {zips} z
        WHERE n.type='iu' and n.uid = u.uid and
	a.uid = n.uid and a.zip = z.zip_code
        "), $nid);
    
      $count = 0;
      // *dan.crouthamel++
      	$multiLocs = array();
      	$offSet = .00003;  //spacing in the X and Y direction for each new marker
      	$curVal = 0;  //current duplicate value of lat/long combination - 1
      	$magVal = 0;  //number of steps from origin to current "square" wall being built
      	$stepVal = 0;  //number of steps from start position of current "square" wall being built.
      	               //In northern hemisphere, this starts at the upper right; southern hemisphere, lower right ... I think that's right :)
      	$numSteps = 0;  //magVal * 2
      	$dirVal = 0;  //0, 1, 2, or 3 - represents current direction of the square being built (see cases below)
      	$posVal = 0;  //current position value along a "square" wall being built, resets to zero when dirVal changes (new segment of square being built)
      	// *dan.crouthamel--

    
      while ($row = db_fetch_object($result)) 
      {
        $count++;
         $newmarker = array();
        if ($mode == 1) {
          // Popup
          $newmarker['rmt'] = $row->nid .'/0';
        }
        elseif ($mode == 2) {
          // Link
          $newmarker['link'] = url('node/'. $row->nid);
        }
        
      	$newmarker['latitude'] = $row->latitude;
	$newmarker['longitude'] = $row->longitude;
	
	// *dan.crouthamel++
	$multiLocs[$newmarker['latitude']][$newmarker['longitude']] += 1;
	

	if ($multiLocs[$newmarker['latitude']][$newmarker['longitude']] > 1)
	{
		$curVal = $multiLocs[$newmarker['latitude']][$newmarker['longitude']] - 1;
		$magVal = (int) ((sqrt($curVal)+1)/2);
		$stepVal = $curVal - pow(2*$magVal-1,2);
		$numSteps = 2*$magVal;
		$dirVal = (int) ($stepVal / $numSteps);
		$posVal = $stepVal % $numSteps;

		switch ($dirVal) {
			//Top to bottom
			//       x
			// x x x |
			// x x x |
			// x x x |				
			case 0:
				$newmarker['longitude'] += ($magVal*$offSet);
				$newmarker['latitude'] += $offSet*($magVal - $posVal);
				break;

			//Right to left
			//       x
			// x x x x
			// x x x x
			// x x x x
			// - - - x				
			case 1:
				$newmarker['latitude'] -= ($magVal*$offSet);
				$newmarker['longitude'] += $offSet*($magVal - $posVal);
				break;

			//Bottom to top
			//         x
			// | x x x x
			// | x x x x
			// | x x x x
			// x x x x x					
			case 2:
				$newmarker['longitude'] -= ($magVal*$offSet);
				$newmarker['latitude'] += $offSet*($posVal - $magVal);
				break;

			//Left to right
			// x - - - x
			// x x x x x
			// x x x x x
			// x x x x x
			// x x x x x						
			case 3:
				$newmarker['latitude'] += ($magVal*$offSet);
				$newmarker['longitude'] += $offSet*($posVal - $magVal);
				break;
		}
	}	
	// *dan.crouthamel--
	      
        $newmarker['markername'] = isset($markertypes[$row->type]) ? $markertypes[$row->type] : 'drupal';
        if (isset($row->marker) && !empty($row->marker)) {
          $newmarker['markername'] = $row->marker;
        }
        $newmarker['opts']['title'] = $row->title;
        $map['markers'][] = $newmarker;
      
      }

      $map['markers'][] = $newmarker;
      $map['zoom'] = 5;
    
     return theme('gmap', array('#settings' => $map));
mrcolon’s picture

I bumped into this thread and think it can help me solve a problem I have with marker clustering. I've tried different kind of google map marker clusterers but they work somewhat but not like I really want them to. So I'm trying to create my own basic clustering logic and I think the code above translated to javascript will help me (I'm Hoping!). But I'm having trouble translating the following three lines -- can someone please help me translate these to javascript:

$multiLocs[$newmarker['latitude']][$newmarker['longitude']] += 1;
if ($multiLocs[$newmarker['latitude']][$newmarker['longitude']] > 1)
{
$curVal = $multiLocs[$newmarker['latitude']][$newmarker['longitude']] - 1;
...

or is there another way to get $curVal that doesn't involve multidimensional array (which if I'm not mistaken these are? anyways java script does not like the following direct translation:
var multiLocs = new Array();
multiLocs[newmarker['latitude']][newmarker['longitude']] += 1;

if ( multiLocs[newmarker['latitude']][newmarker['longitude']] > 1 )
{
curVal = multiLocs[newmarker['latitude']][newmarker['longitude']] - 1;

and I'm not a power javascript developer either :-)

TIA,
Carlos

aprice42’s picture

@mrcolon: did you get your javascript solution to work? I am still struggling with getting nodes with the same lat. and long. to display properly in a gmap view. Any advice you can offer would be greatly appreciated.

Thanks,
Andy

mrcolon’s picture

Hi Andy,

Yes, I finally got my the above code from dan converted to javascript and working. It was a big sense of relief since I couldn't get any other solution working!!! What follows is the core of it. The variables are pretty much the same as what dan had defined. You may need to play with your offSet variable until you get desired results. "marker" in this code is the new marker being displayed and markersArray[] is the array of markers already displayed. The logic tries to position marker by comparing its distance from others already in the array. So I needed to defined a new variable call overDist (could be named better I guess). When the new marker has been analyzed against the existing set then it is finally adjusted to its new position and displayed(app specific). I have to make adjustments throughout and still trying to make it more efficient. If anyone has any ideas on how to make this more efficient please advise! I would like to thank Dan for sharing his original code! It was a life saver at some point!!!

var count = 0;
var newmarkerLatOffset = 0;
var newmarkerLngOffset = 0;
for (var i = 0; i < markersArray.length; ++i)
{
if ( markersArray[i].getLatLng().distanceFrom(marker.getLatLng()) < overDist )
{
count++;
curVal = count; // -1?
magVal = Math.round((Math.sqrt(curVal)+1)/2);
stepVal = curVal - Math.pow(2*magVal-1,2);
numSteps = 2*magVal;
dirVal = Math.ceil(stepVal / numSteps);
posVal = stepVal % numSteps;

switch (dirVal)
{
//Top to bottom
// x
// x x x |
// x x x |
// x x x |
case 0:
newmarkerLngOffset += (magVal*offSet);
newmarkerLatOffset += offSet*(magVal - posVal);
break;

//Right to left
// x
// x x x x
// x x x x
// x x x x
// - - - x
case 1:
newmarkerLatOffset -= (magVal*offSet);
newmarkerLngOffset += offSet*(magVal - posVal);
break;

//Bottom to top
// x
// | x x x x
// | x x x x
// | x x x x
// x x x x x
case 2:
newmarkerLngOffset -= (magVal*offSet);
newmarkerLatOffset += offSet*(posVal - magVal);
break;

//Left to right
// x - - - x
// x x x x x
// x x x x x
// x x x x x
// x x x x x
case 3:
newmarkerLatOffset += (magVal*offSet);
newmarkerLngOffset += offSet*(posVal - magVal);
break;

default:

} // switch

var markerLatLng = marker.getLatLng();
var newmarker = new Array();
newmarker['latitude'] = markerLatLng.lat()+newmarkerLatOffset;
newmarker['longitude'] = markerLatLng.lng()+newmarkerLngOffset;
newLatLng = new GLatLng( newmarker['latitude'],newmarker['longitude'] );
marker.setLatLng(newLatLng);

} // if
} // for

HTH,
Carlos

khosman’s picture

subscribe

jmorenobl’s picture

Hello,

I would like to use that javascript code, but I don't know where to put it.

Thanks in advance!

eiland’s picture

Version: 5.x-1.0-beta2 » 6.x-1.1

subscribe

eiland’s picture

Trying to merge with #679804: Patch for 4 new features in GMap but its not so easy....

eiland’s picture

StatusFileSize
new10.05 KB

voila

rooby’s picture

Status: Active » Needs work

I haven't had a chance to look at this yet but is it possible to provide a patch file instead of a tar?

It is much easier to review things that way.

There is information regarding patches and how to create them at http://drupal.org/patch

Also, when you have a patch that needs review, set the status to "Needs review" so people will know there is something that needs review/testing.

For more information on statuses see http://drupal.org/node/156119

eiland’s picture

Version: 6.x-1.1 » 6.x-1.x-dev
Status: Needs work » Needs review
StatusFileSize
new6.01 KB

After trying to get CVS to work, I scrolled down to the explanation using diff.
I hope you can understand the attached patch.

rooby’s picture

Status: Needs review » Needs work

Cool, thanks a lot for making the patch.

A couple of quick things that I notice:

There are some coding standards issues with the patch, which are mostly related to indenting, no spaces around some operators and the use of camel case instead of underscores for variable names.
You can see the full list at http://drupal.org/coding-standards

Also,
Patches should apply with:

patch -p0 < patchfile.patch

When creating a diff between two directories from outside those directories it makes a patch file that applies with:

patch -p1 < patchfile.patch

Which will confuse some people as they will get unusual messages if they use -p0.

You can avoid this by editing your patch file after creating it.
For example in your patch you would change:

+++ gmap_crouthamel/gmap_location.module	2010-10-18 11:59:21.000000000 +0200

to:

+++ gmap_location.module	2010-10-18 11:59:21.000000000 +0200

and:

+++ gmap_crouthamel/gmap_plugin_style_gmap.inc	2010-10-18 11:54:42.000000000 +0200

to:

+++ gmap_plugin_style_gmap.inc	2010-10-18 11:54:42.000000000 +0200

Otherwise, another way to avoid it is instead of using (from outside the two directories):

diff -rup gmap gmap_crouthamel > gmap_crouthamel.patch

You use this (from inside the new directory, ie. gmap_crouthamel.patch):

diff -rup ../gmap . > gmap_crouthamel.patch

Another thing that is helpful to patch reviewers is having a descriptive name for your patch file,
There is more information on this at http://drupal.org/patch/submit under the "Name your patch" section.

eiland’s picture

So besides the patch, did you review the working mechanics of it?
I hate to be rude, but you asked for a patch, I gave you one, admittedly not perfect, but hey.
And now you're talking not at all anymore about the topic thread.
This issue isn't my own personal how can I make a patch course.

rooby’s picture

Sorry to be picky but no I wasn't at a computer where i could test so I just had a quick look at the patch visually.

I'm testing patches now so I'll have a look shortly.

I know it can be annoying to have people at you about coding standards and things but it does make thing a bit easier to review. And when you have issue queues with hundreds of issues the easier the better.
Also, if you look around issue queues you will find that the majority of module maintainers won't commit patches that don't adhere to coding standards and a lot won't review patches that don't apply properly.
As annoying as it might be that's the way it is.
If it wasn't me that pointed these things out someone else would have.

Also, you don't have to be stupid about the file naming, I was trying to be polite and point you to some useful drupal documentation pages, which you obviously didn't even read.

rooby’s picture

I have had a bit of a test and it seems to work fine (I haven't looked at the maths yet as my brain won't take that at this time of night).

I think the spacing of the markers is good, and it is pretty non-intrusive so I don't really see a problem with making it the default functionality (as opposed to having a setting that people can enable) but it may still be better as an option that people can enable/disable for whatever reason they have.
I still have to test it with clusterers and see what happens.

I will still review further later but it's bed time for now.

There are a couple of things I have noticed though:

1. The functionality should also be added to the gmap_location_user_page() function.

2. There is lots of duplicate code that can be removed.

+++ gmap_location.module 2010-10-18 11:59:21.000000000 +0200
@@ -283,6 +297,68 @@ function gmap_location_node_page($nid = 
+  if ($multi_locs[$newmarker['latitude']][$newmarker['longitude']] > 1)
+  {
+   $cur_val = $multi_locs[$newmarker['latitude']][$newmarker['longitude']] - 1;
+   $mag_val = (int) ((sqrt($cur_val)+1)/2);
+   $step_val = $cur_val - pow(2*$mag_val-1,2);
+   $num_Steps = 2*$mag_val;
+   $dir_val = (int) ($step_val / $num_Steps);
+   $pos_val = $step_val % $num_Steps;
+   ¶
+   switch ($dir_val) {
+    //Top to bottom
+    //       x
+    // x x x |
+    // x x x |
+    // x x x |    ¶
+    case 0:
+     $newmarker['longitude'] += ($mag_val*$off_set);
+     $newmarker['latitude'] += $off_set*($mag_val - $pos_val);
+     break;
+     ¶
+    //Right to left
+    //       x
+    // x x x x
+    // x x x x
+    // x x x x
+    // - - - x    ¶
+    case 1:
+     $newmarker['latitude'] -= ($mag_val*$off_set);
+     $newmarker['longitude'] += $off_set*($mag_val - $pos_val);
+     break;
+     ¶
+    //Bottom to top
+    //         x
+    // | x x x x
+    // | x x x x
+    // | x x x x
+    // x x x x x     ¶
+    case 2:
+     $newmarker['longitude'] -= ($mag_val*$off_set);
+     $newmarker['latitude'] += $off_set*($pos_val - $mag_val);
+     break;
+     ¶
+    //Left to right
+    // x - - - x
+    // x x x x x
+    // x x x x x
+    // x x x x x
+    // x x x x x      ¶
+    case 3:
+     $newmarker['latitude'] += ($mag_val*$off_set);
+     $newmarker['longitude'] += $off_set*($pos_val - $mag_val);
+     break;
+   }
+  } ¶

All of the code inside this if statement can live in it's own function, which takes $cur_val as a parameter and returns the lat lon pair.
That way the code is only in one place.

I won't have time to make these changes for a couple of days but I will if no one does in the meantime.
I have attached an updated patch that has had a bit of cleanup.

Powered by Dreditor.

rooby’s picture

Status: Needs review » Needs work

Forgot to change the status.

ilegolas’s picture

I tried the patch but it didn't work out for the gmap_plugin_style_gmap.inc file. Did anyone have problems with that?

eiland’s picture

Try the attachs in #25 instead.

eiland’s picture

Status: Needs work » Active

See an example

rooby’s picture

nagiek’s picture

subscribe

summit’s picture

Subcribe, needing clustering of nodes using gmap/views. Not able to get ti to work with latest views 3.-dev.
greetings, Martijn

mry4n’s picture

Subscribe

jim kirkpatrick’s picture

+1

ikeigenwijs’s picture

subscribe

mry4n’s picture

After thinking about this some more, it seems to me that the correct way to go about this is to not expect GMap to handle a bunch of markers at one location.

If we think about this in terms of a database, there could be many things that have the same location. So, if we had a bunch of events, for example, and a bunch of locations, we'd have a table that lists location IDs with event IDs and there would be a 1-to-many relationship of locations to events (e.g. the location IDs would reoccur in the table many times, but the event IDs only once).

What this means in Drupalandia is that we create Location nodes that have a nodreference field that allows an unlimited number of references to Events nodes. Now, when we create our view there will be only one distinct location for every marker -- as it should be, right? There's really no such thing as more than one location at a location.

When you include the nodereference field in the view, links to those other locations will appear in the info window and now all of your events are at the same location.

So, is this really an issue, then?

jim kirkpatrick’s picture

Status: Active » Needs review

Thanks for the idea Mike, but I'm afraid I don't agree... This certainly is an issue for us and many others - and an issue that lies within the output of this module.

So:
* Should users be expected to look up a location via node reference when they know only the address? No, of course not.
* Should every site normalise their locations just because this module cannot handle overlapping coordinates? No, of course not.
* You're right to say it makes no sense to have "more than one location at a location", but there are certainly more than one location at a postcode - especially in a place like the US with low resolution postcodes.

Your idea might work for your site, but not ours (or any other site I've made with Drupal and Location) unfortunately.

The patches in this thread do an excellent job, and something along these lines needs submitting soon. It's a display issue, not a data normalisation issue.

ikeigenwijs’s picture

Hello all

I just want on a map on one location all the different titel fields linked to that location.
I will test the latest patch shortly.

Ore is there an other setting i could use?
I also tried the different:
No manager (use GMap API directly)
Google's GMarkerManager
GMaps Utility Library MarkerManager
GMaps Utility Library MarkerClusterer
Jef Poskanzer's Clusterer
Martin Pearman's ClusterMarker

but none did what i wanted, and yes i got the files in the tird party folder.
any tips are welcome.
thx a lot,

mry4n’s picture

Thanks for the response, Jim.

I think the perspective I'm coming from is different, because I'm thinking in terms of importing nodes with location info, which will never be edited, and that's the only way they'll be added to my site.

On a separate note, I'm wondering how this patch will work when, for example, you have two locations next to one another which have, say, 50 nodes attached to each. I assume there will be overlap?

brunorios1’s picture

sub... need the #44 functionality too...

rooby’s picture

Status: Needs review » Needs work

While it makes logical sense that multiple locations can't be on the exact location, that doesn't really suit a lot of peoples website use cases.

As an example:
When displaying points on a map you might have a whole bunch of shop nodes that are all shops within a single building, like a small mall or something.
While these shops are technically not all occupying the exact same location, they are in the same building, which is at the same point on a map (if using geocoding the address and it's lat/lon would likely be the same for all the shops).

Now either you have a single map marker, which contains all the info about all the shops (not feasible), or a bunch of links that link off to each of the shop nodes where all the info can be seen (feasible depending on your use case, potentially not super user friendly) OR you have multiple markers like this issue would allow for, which means each marker popup can be for it's own store. This has it's own usability issues but it is definitely a case that could be catered for, especially seeing as the location module does nothing to stop people putting multiple locations in the same place.
So having an option that people can turn on or off is the best solution as it caters to everyone.

Also, as per #31 this is needs work as the patch is not in a committable state.

brunorios1’s picture

another use case:

if i have 2 places with various events in different dates and i want to list all the places in the map with links to all the events...

hnln’s picture

subscribe

commonpike’s picture

Working on 7.x-1.x-dev, I've been able to get this done fairly simply.

The below code walks through the markers on the map, and if it finds
markers with the same location, it nudges them off a bit (in fact, it spirals
them outwards, if you have enough markers at one spot - tweek to your likings).
Google maps will see the slight different in lat/long and show a marker with
a bit more outline (well, probably overlapping icons, but it works quite well)

first, I needed to comment,
at line 1400 in gmap.module (function template_preprocess_gmap_view_gmap).

// Theme the map.
// $vars['map'] = drupal_render($vars['map_element']);

this is a hack :-/ I wonder why its needed.

after that i could add below code to my themes template.php

function MYTHEME_preprocess_gmap_view_gmap(&$vars) {
	/**
	* Fixes the problem of multiple markers appearing on the same spot.
	* http://drupal.org/node/530328
	*/
	
	// set up the 2 for loops to be more efficient (never compare the same 2 markers twice)
	for ($outer=0; $outer < count($vars['map_object']['markers']); $outer++) {
		$cc=0;
		$outer_place =& $vars['map_object']['markers'][$outer];
		for ($inner = $outer+1; $inner < count($vars['map_object']['markers']); $inner++) {
			$inner_place =& $vars['map_object']['markers'][$inner];
			if ($outer_place['latitude'] == $inner_place['latitude'] && 
				$outer_place['longitude'] == $inner_place['longitude']) {
					$cc++;
					// nudge the location of the inner place
					$inner_place['latitude'] += -0.05*sqrt($cc)*sin($cc*45);
					$inner_place['longitude'] += -0.05*sqrt($cc)*cos($cc*45);
				}
		}
	}

	// Theme the map - didnt work.
	// $vars['map'] = theme('gmap', array('#settings' => $vars['map_object']));
	
	$vars['map_element'] = array(
		'#type' => 'gmap',
		'#gmap_settings' => $vars['map_object'],
	);
	// Theme the map.
	$vars['map'] = drupal_render($vars['map_element']);
	  
}

$2c
*-pike

jrao’s picture

pike's method is pretty close, to do this without hacking, add the following (only tested on D6) to template.php:

function MYTHEME_gmap($element) {
if (isset($element['#settings'])) {
$offset = 0.5;
$markers =& $element['#settings']['markers'];
for ($outer=0; $outer < count($markers); $outer++) {
$cc=0;
$outer_place =& $markers[$outer];
for ($inner = $outer+1; $inner < count($markers); $inner++) {
$inner_place =& $markers[$inner];
if ($outer_place['latitude'] == $inner_place['latitude'] &&
$outer_place['longitude'] == $inner_place['longitude']) {
$cc++;
// nudge the location of the inner place
$inner_place['latitude'] += -$offset*sqrt($cc)*sin($cc*45);
$inner_place['longitude'] += -$offset*sqrt($cc)*cos($cc*45);
}
}
}
}
return theme_gmap($element);
}

jjbellamy’s picture

jrao (#51), thanks for your message. Are you saying that by adding to my template.php file, I will be able to see multiple markers with same latitude/longitude? Any other settings to make? Please let me know. Thanks a million.

jrao’s picture

It's been a long time so I'm not sure, but yes, I think this is all the change you need to make.

webservant316’s picture

subscribe - need to fix this also asap.
I added #51 to my template, but with no effect.

ok got it to work, needed to lessen the offset. the setting in #51 sent the markers too far out. In fact I change the algorithm on my site to display the overlapping markers in a straight line right of the first point. This seemed more intuitive to communicate that all the markers shared the exact same location.

jjbellamy’s picture

Thanks jrao. I was able to use the code and can now see all markers at same location. I tweaked the figures in the algorithm to bring the markers closer. It works. Thanks a million.

webservant316’s picture

Here is the solution I went with - http://drupal.org/node/1139088#comment-5956720. This allows mutiple markers on the exact same long/lat with a list popup instead. The effect is nicer for the user when they magnify down to the street level.

johnv’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev

#50 works fine. I just modified gmap.module (function template_preprocess_gmap_view_gmap).
Like #54, I like a straight line better, so added '+= 0.01' to each lat/lon.

podarok’s picture

Status: Needs work » Needs review

tag

Status: Needs review » Needs work

The last submitted patch, gmap-multiple_markers_at_same_point-284481-31.patch, failed testing.

jkingsnorth’s picture

I haven't been able to get the solutions in this thread working. I was wondering if anyone had any idea how to achieve this a few more months down the line? (I see this issue has been around for 5 years now though!)

Edit - I've been able to get the hack in #50 working which is good enough for now

Anonymous’s picture

This is the working code for D7, thx jrao for the helpful d6 code.

function MYTHEME_gmap($element) {
  dpm($element);
  if (isset($element['element']['#gmap_settings'])) {
  $offset = 0.5;
  $markers =& $element['element']['#gmap_settings']['markers'];
    for ($outer=0; $outer < count($markers); $outer++) {
    $cc=0;
    $outer_place =& $markers[$outer];
      for ($inner = $outer+1; $inner < count($markers); $inner++) {
      $inner_place =& $markers[$inner];
        if ($outer_place['latitude'] == $inner_place['latitude'] &&
        $outer_place['longitude'] == $inner_place['longitude']) {
          $cc++;
          // nudge the location of the inner place
          $inner_place['latitude'] += -0.01*sqrt($cc)*sin($cc*45);
          $inner_place['longitude'] += -0.01*sqrt($cc)*cos($cc*45);
        }
      }
    }
  }
return theme_gmap($element);
}
podarok’s picture

Component: Code » Documentation
Category: Feature request » Support request
Issue summary: View changes
Status: Needs work » Patch (to be ported)
Berliner-dupe’s picture

@FeanorCC

Thank you for the code in #61....

It works but now the markers with same lat/lon are straggling all over the city ... between markers are 5 km or more space and this is not useful. Between marker on botton and on top are now over 30 km ... although they have the same address?

When markers has same adress i need only shift 5 pixels between ...

Is this possible with your code?

jkingsnorth’s picture

I'm not sure this is the right approach (#61) - in case people are actually trying to navigate to a certain location using the map. The marker could now be in a completely different location if there are 10 or so points in the same place. Perhaps something more like the OverlappingMarkerSpiderfier is a better approach? (https://github.com/jawj/OverlappingMarkerSpiderfier)

Frederic wbase’s picture

I've started with the solution from FeanorCC, but i changed the code completely. For me it is working now with the latest D7 gmap

/**
 * Implements theme_gmap
 * used for displaying multiple locations with same lat/long
 */
function your_theme_gmap($element) {

  if (isset($element['element']['#gmap_settings'])) {
  
  foreach($element['element']['#gmap_settings']['markers'] as $marker){
    if(isset($markersO[$marker['latitude'].','.$marker['longitude']])){
      $markersO[$marker['latitude'].','.$marker['longitude']]['text'] .= $marker['text'];
    }else{
      $markersO[$marker['latitude'].','.$marker['longitude']] = $marker;
    }
  }
  
  $i = 0;
  foreach($markersO as $value){
    $markers[$i] = $value;
    $i++;
  }
  
  
  $element['element']['#gmap_settings']['markers'] = $markers;

  }
  
  return theme_gmap($element);
  
}

jkingsnorth’s picture

Status: Patch (to be ported) » Needs work

Setting this back to needs work due to issues raised in #63 & #64.

However, #65 is a very elegant solution which is working for me at present. Perhaps a patch could be based on this? I can see issues arising when there are lots and lots of events in the same location, but at the moment this is working fine for me - thanks Frederic.

Anonymous’s picture

@Berliner
@.John

My posted code use a big distance between the markers, and you're right, the location is not on the correct point. But you can minimize the distance very easy.

For example:

$inner_place['latitude'] += -0.00020*sqrt($cc)*sin($cc*45);
$inner_place['longitude'] += -0.00020*sqrt($cc)*cos($cc*45);

Maybe the solution from Frederic works better, I have not tested it, but i will soon ;) Thank you for that Frederic.

alaugh’s picture

Thanks, everyone, for working on this. Frederic, I would like to try your solution but I am confused about where to place this code that you have contributed. I'm not especially skilled at code so any pointers you can offer would be greatly appreciated. Can you dumb it down for me?

Thanks in advance.

sadashiv’s picture

Hi,

I found a sandbox at https://www.drupal.org/sandbox/ethanhinson/2282553

It worked for me.

Hth,
Sadashiv.

rooby’s picture

Component: Documentation » Code
Category: Support request » Feature request

I don't think this should be a support request. It should be a feature request.

Even though there are code examples here of overriding the themeing of the gmap I think this doesn't seem like something people should have to override into a theme function or preprocessor, it is something that belongs deeper in the module than the theme function.

It is pretty complex code that themers shouldn't have to deal with and it's an issue of functionality, not visual display.

There could be an option in the settings to enable this functionality.

There was also no reasoning given in #62 when it was changed to a support request.

SeanA’s picture

Title: GMap Views able to show distinct markers or links for places w/same lat/long? » GMap Views - show distinct markers or links for places with same lat/long
Version: 7.x-1.x-dev » 7.x-2.x-dev
Related issues: +#1139088: Displaying multiple markers that have the same lat/long coordinates in GMap Views