> Date: Thu, 12 Jan 2012 22:52:18 +0100
> From: wmgcnfg@web.de
> To: mkgmap-dev@lists.mkgmap.org.uk
> Subject: Re: [mkgmap-dev] [Patch v3] LocationHook with new Quadtree
>
> > Hi WanMil,
> >
> > thanks for the quick response.
> >
> > > some ideas and questions:
> > >
> > > * BoundaryQuadTree.Node.add always performs a costly intersect of the
> > > area, also if the area is completely within the bbox. Maybe it's better
> > > first to check if the bbox contains the area (or area.getBounds()).
> > Good point. I'll try that.
> >
> > >
> > > * I don't understand the following part in Node.add:
> > > ---
> > > // optimization: don't add equal areas, only add the tags
> > > // we test only against the last element because that is likely
> > > // to match
> > > if (numNodes > 0 && a.equals(nodes.get(numNodes-1))){
> > > addMissingTags(nodes.get(numNodes-1).tags, bTags);
> > > return;
> > > }
> > > ---
> > > a is an area and nodes.get returns a NodeElem so equals will always be
> > > false.
> > > I think you want to compare to nodes.get(..).area but I do not
> > > understand that either. Why should two areas be equal?
> >
> > argh! This error was introduced while I cleaned the code :-(
> > Of course I want to compare the areas. We add all boundaries to the
> > tree, even those with level=2.
> > Since the boundary list is sorted so that they appear last, it is very
> > likely that the area completely
> > covers the bbox of the tree. In this case the area will be the bbox.
>
> Is that really a performance improvement?
> admin_level=2 boundaries are splitted anyhow during creation of the
> tree. An area that is equal to a rectangle can perform a very easy and
> quick contains test. So checking for equality probably will be more
> costly than leaving it as it is?
Hmm, it was an improvement at some stage before I optimized other parts, now it seems
to decrease performance quite a lot.
Remove it for now.
>
> >
> > >
> > > * LocationHook.mkgmapTagsArray starts with an empty string element. I
> > > don't like that.
Yes, looks strange, but without it the level value would not match the position
in the array. I'll add a comment for this, okay?
I also want to avoid calling getTag with an empty key, so I think we need
for (int i=1;i < ...)
> > >
> > > * for (int i = 12; i >= 1; --i){
> > > if (elem.getTag(mkgmapTagsArray[i] ) != null)
> > > res |= (1 << i);
> > > }
> > >
> > > =>
> > >
> > > for (int i = 0; i mkgmapTagsArray.length; i++) {
> > > if (elem.getTag(mkgmapTagsArray[i] ) != null)
> > > res |= (1 << i);
> > > }
> > >
> > > Counting down is quite unusual and should only be done if there is a
> > > real reason for it.
> >
> > You are right, there is no longer a reason for it. I'll change that. I
> > used this loop together
> > with a bitmask and a call to Integer.highestOneBit()
> >
> > >
> > > * I don't understand why you need a merge() method. Could you explain
> > > what you are doing in this method and why it's required?
> > The get method() of the tree returns the data for the first area that
> > contains the coord.
> > This area should contain all tags of the area itself plus those from
> > areas intersecting it.
> > Maybe this is not correct?
>
> Sounds wrong. If Area a1 is intersected by a2 only in 10% of its area
> then an element located in the 90% that does not intersect would be
> tagged with a1 and a2?
>
The merge() first creates a new nodeElem with the intersection, it merges the tags into this
and subtracts the intersection from the others, so only the 10% part gets more tags.
Thinking again about this I might not need both subtract() calls since I move the intersection part
before the others .