<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:"Segoe UI";
        panose-1:2 11 5 2 4 2 4 2 2 3;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoAutoSig, li.MsoAutoSig, div.MsoAutoSig
        {mso-style-priority:99;
        mso-style-link:"E-mail Signature Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";}
span.E-mailSignatureChar
        {mso-style-name:"E-mail Signature Char";
        mso-style-priority:99;
        mso-style-link:"E-mail Signature";
        font-family:"Calibri","sans-serif";}
span.e-mailsignaturechar0
        {mso-style-name:e-mailsignaturechar;
        mso-style-priority:99;
        font-family:"Calibri","sans-serif";}
span.EmailStyle20
        {mso-style-type:personal;
        font-family:"Arial","sans-serif";
        color:windowtext;}
span.EmailStyle21
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle22
        {mso-style-type:personal;
        font-family:"Arial","sans-serif";
        color:navy;}
span.EmailStyle23
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.25in 1.0in 1.25in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang=EN-US link=blue vlink=purple>
<div class=Section1>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>Chris,<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>I
think as long as your algorithm, server or client-side, knows how to turn the interleave
back into lat/lon (so it’s a 1:1 mapping), then it doesn’t really matter if you
have extra 0’s in front or not. The project I used this on was based in
the Pacific Northwest, not globally, and so I never had to deal anything too
far left of the decimal place. <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>My
script was server-side, and it returned somewhere between 80 – 100 pts for
every view – if there would be more than 100 I’d loop through some of the pts
again with a couple more digits lopped off the interleave (bigger grid). <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>In
python, an early draft of the main clustering function looked something like
this: <a href="http://rafb.net/paste/results/ePwPB010.html">http://rafb.net/paste/results/ePwPB010.html</a>
(I think this might be online for just a couple days). Later I added
stuff so you could add to different clusters based on what ‘type’ of point it
was, so each cluster had only similar points within it…<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>The
script was fast enough – and worked great in the map I was using because it
didn’t have panning capability. However, I had hoped to use it in a
Google Maps, and like a ka-map style application, you don’t want to have to
re-request new points every time you pan the map. Basing it on difference
between pixels implies you could come up with an algorithm that works on the
entire layer for each zoom level. Then you can precalculate, and put the
cluster results in a new table. As people add new pts to the database,
you could either add a trigger if it’s a rare occurrence, or deal with the
additional few points manually and re-calculate nightly or whatever. <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>This
would work great assuming people aren’t needing to make arbitrary queries
for subsets of points, but in my case they were, so points really had to be
dynamically created, and I never got around to coming up with a good way to
figure out how to tell how many pts to put on a given screen, and not have to
deal with re-requesting new pts for every major pan action.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>A
couple weeks ago on #openlayers I was discussing this with bitner, and he had
some great ideas on the topic. He just mentioned another great idea
which is starting a wiki on the topic – as you can see I’m certainly no expert
on it, but maybe someone will be able to come up with a wiki link to this
really interesting subject.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>
-Josh<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<div>
<div style='border:none;border-top:solid #91C0FF 1.0pt;padding:3.0pt 0in 0in 0in'>
<p class=MsoNormal><b><span style='font-size:9.0pt;font-family:"Segoe UI","sans-serif"'>From:</span></b><span
style='font-size:9.0pt;font-family:"Segoe UI","sans-serif"'> Christopher Brown
[mailto:chris@basebloc.com] <br>
<b>Sent:</b> Sunday, October 22, 2006 7:37 AM<br>
<b>To:</b> 'Josh Livni'; ka-map-users@lists.maptools.org<br>
<b>Subject:</b> RE: [ka-Map-users] Efficient Point Collision<o:p></o:p></span></p>
</div>
</div>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'>Hi Josh,<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'>I just read through the whole thread on the PostGIS list more
thoroughly than I did before I made the last post and the discussion was very
interesting especially in relation to breaking the extent into a grid as this
is the only way I can think to reduce the size of the server-side loops. I have
a couple of questions though, the example in the thread states that the
interleave is produced in the following format – “42.987654, -072.123456 =>
-07422.192837465564 LLLlLl.LlLlLlLlLlLl” this will work for collision when it
is just a case of number order but for determining which marker is in which
square within a grid wouldn’t it need to be in the following format
“042.987654, -072.123456 => -007422.192837465564 LILlLl.LlLlLlLlLlLl” as to
query if a point is somewhere within the extent x1/y1 and x2/y2 we need x and y
to have an equal unit length if we are to achieve this through the interleave
value (as apposed to a series of If statements) by appending zero’s to the
front of the value? This way we can determine if the point is within the grid
square extent simply by checking if our point interleave is bigger than extent
interleave one and smaller than extent interleave two.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'>Did you arrive at a final solution after the discussions on this
PostGIS list, if so what was your end solution and how did it work out?<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'>Regards,<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'>Chris<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'><o:p> </o:p></span></p>
<div>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>~~~~~~~~~~~~~~~~~~~~~~~~~~~<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Christopher Brown<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Head of Internet Development<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Base Bloc Cambodia<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>#33, 123, Phnom Penh, Cambodia. <o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>P.O. Box 2086<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'><a href="http://www.basebloc.com">www.basebloc.com</a><o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Mobile (+855) 12 315 302</span><span style='color:navy'><o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Office (+855) 23 222 015<o:p></o:p></span></p>
</div>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:navy'><o:p> </o:p></span></p>
<div>
<div class=MsoNormal align=center style='text-align:center'><span
style='font-size:12.0pt'>
<hr size=2 width="100%" align=center>
</span></div>
<p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span
style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> Josh Livni
[mailto:josh@livniconsulting.com] <br>
<b>Sent:</b> 21 October 2006 22:34<br>
<b>To:</b> 'Christopher Brown'; ka-map-users@lists.maptools.org<br>
<b>Subject:</b> RE: [ka-Map-users] Efficient Point Collision</span><span
style='font-size:12.0pt'><o:p></o:p></span></p>
</div>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>I
think client side is always going to be slow for large numbers of markers (more
than a few hundred); just downloading all the marker pts and a most basic
javascript to go over them is reasonably time consuming. I personally
think some kind of clustering on server side might be the most reasonable thing
for large numbers of markers. <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>That
said, one thing that might add to your current method of ordering of markers by
the xcoord, server or client-side, is to order by an interleave instead.
I once implemented something along the lines of what is described here, and it
was quite fast: <a
href="http://www.postgis.org/pipermail/postgis-users/2006-March/011430.html">http://www.postgis.org/pipermail/postgis-users/2006-March/011430.html</a>
<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'>
-Josh<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<p class=MsoNormal><span style='font-family:"Calibri","sans-serif";color:#1F497D'><o:p> </o:p></span></p>
<div>
<div style='border:none;border-top:solid #91C0FF 1.0pt;padding:3.0pt 0in 0in 0in'>
<p class=MsoNormal><b><span style='font-size:9.0pt;font-family:"Segoe UI","sans-serif"'>From:</span></b><span
style='font-size:9.0pt;font-family:"Segoe UI","sans-serif"'>
ka-map-users-bounces@lists.maptools.org
[mailto:ka-map-users-bounces@lists.maptools.org] <b>On Behalf Of </b>Christopher
Brown<br>
<b>Sent:</b> Friday, October 20, 2006 11:53 PM<br>
<b>To:</b> ka-map-users@lists.maptools.org<br>
<b>Subject:</b> [ka-Map-users] Efficient Point Collision<o:p></o:p></span></p>
</div>
</div>
<p class=MsoNormal><o:p> </o:p></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Hi
Guys,<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Whilst
we’re on the subject I have also been working on a point collision system,
except I’m using addObjectGeo() to lay down the marker instead of any of the
XML related methods. I have the script working fine and it behaves in the same
way as flickr ( <a href="http://flickr.com/map/">http://flickr.com/map/</a> )
with discs of relative sizes which show the number of points within. <o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>To
break it down each time a marker is placed it loops through each already placed
marker stored in a makers array to test for collision based on pixel distance
using “var distance = Math.sqrt(Math.pow((Math.pow((thisNodeLeft -
otherNodeLeft),2) + Math.pow((thisNodeTop - otherNodeTop),2)),1));”, this
system works great for around 50 markers but often my apps will place 500+
makers which runs just fine until I collision check them as the loop just
becomes huge and obviously causes the browser to hang.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>To
counter this I made SQL output the markers in order of their X coordinate then
instead of checking every marker, I just check against the last 10 markers to
me drawn and the last 10 will generally be the closest ones as the X positions
will all be similar if they are colliding, this method works 99% of the time at
scales where the marker density is not too high, but clearly wouldn’t work as
it does with flickr when zoomed right out so the density is extremely high and
the disks can contain 100+ markers, I would like to be able to achieve this
effect but just can’t think of a way that is both dynamic and not going to
bring the server or the client to a crawl.<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>I
don’t need code, just some inspiration on how to achieve this, all ideas and
suggestions welcome!<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Cheers,<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'>Chris<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif"'><o:p> </o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>~~~~~~~~~~~~~~~~~~~~~~~~~~~<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Christopher Brown<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Head of Internet Development<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Base Bloc Cambodia<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>#33, 123, Phnom Penh, Cambodia. <o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>P.O. Box 2086<o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'><a href="http://www.basebloc.com">www.basebloc.com</a><o:p></o:p></span></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Mobile (+855) 12 315 302</span><o:p></o:p></p>
<p class=MsoAutoSig><span style='font-size:8.0pt;font-family:"Arial","sans-serif";
color:navy'>Office (+855) 23 222 015<o:p></o:p></span></p>
<p class=MsoNormal><span style='font-size:10.0pt'><o:p> </o:p></span></p>
</div>
</body>
</html>