Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#3406 closed defect (fixed)

shape->classindex is always 0

Reported by: hopfgartner Owned by: aboudreault
Priority: normal Milestone: 6.0 release
Component: MapScript-PHP Version: unspecified
Severity: normal Keywords:
Cc: nhermann, dmorissette, sdlime

Description

It seems that in PHP MapScript the classindex is always 0 for all shapes.

Software: MapServer 5.6.1 Platform: Centos 5.4, 64 bit Data source: PostGIS 1.4.1 on PostgreSQL 8.2

Reference: http://lists.osgeo.org/pipermail/mapserver-users/2010-March/065017.html

Attachments (4)

test.map (2.6 KB ) - added by hopfgartner 14 years ago.
Test map file
test.sql (553 bytes ) - added by hopfgartner 14 years ago.
Test data
test_classindex.php (301 bytes ) - added by hopfgartner 14 years ago.
PHP test script
test.png (1.0 KB ) - added by hopfgartner 14 years ago.
test map image, showing the correctness of the map file + data

Download all attachments as: .zip

Change History (14)

by hopfgartner, 14 years ago

Attachment: test.map added

Test map file

by hopfgartner, 14 years ago

Attachment: test.sql added

Test data

by hopfgartner, 14 years ago

Attachment: test_classindex.php added

PHP test script

by hopfgartner, 14 years ago

Attachment: test.png added

test map image, showing the correctness of the map file + data

comment:1 by aboudreault, 14 years ago

I tested the same thing in Python MapScript and got the same result.

import mapscript

map = mapscript.mapObj("test.map")
layer = map.getLayerByName("test");
layer.open()
layer.whichShapes(map.extent)
shape = layer.nextShape()
while (shape):
    print "index: ",shape.index," classindex: ",shape.classindex;
    shape = layer.nextShape()

layer.close()

----- result ---------
index:  1  classindex:  0
index:  2  classindex:  0
index:  3  classindex:  0
index:  4  classindex:  0

I assume all mapscript bindings have the problem. I'm going to do further investigation.

comment:2 by nhermann, 14 years ago

Cc: nhermann added

comment:3 by aboudreault, 14 years ago

The problem is that the classindex is just not set in the nextShape/getShape methods. In these functions, we can't really know what is the classindex of the shape. The classindex is got during the map draw and the scaledenom is needed to get the proper classindex.

comment:4 by aboudreault, 14 years ago

A possible solution could be to expose a new method in MapScript. ie. layer->getClassIndex(shape, scaledenom, classgroup, numclasses). A prorotype similar to the msShapeGetClass() function in maputil.c.

comment:5 by dmorissette, 14 years ago

Cc: dmorissette sdlime added
Milestone: 6.0 release

I think this behavior is to be expected since the class index does not come with the data, it is determined after evaluating the class expressions, which has a non-negligible cost and is done only when needed (as Alan wrote: at map draw/query time).

I agree that a new method such as layer->getClassIndex() is probably the way to go.

Adding Steve to CC to get his opinion.

comment:6 by aboudreault, 14 years ago

I'm going to implement this method. Since it's a small method, I could modify it on Steve's comments later.

comment:7 by aboudreault, 14 years ago

Resolution: fixed
Status: newclosed

The layerObj->getClassIndex has been added. Here's its prorotype:

int getClassIndex(shape, scaledenom [, classgroup,  numclasses])
 - shape: the shape to get the class index
 - scaledenom: the current map scaledenom
 - classgroup: An array of class ids to check. (optional: we check all the layer's classes by default)
 - numclasses: The number of classes in classgroup (optional, only kept to be consistent with SWIG) 

Note: if you want to use map->scaledenom, be sure it has been computed. You can be forced to call a map->prepageImage() to compute the scale of the map.

Fixed and committed in r10031.

comment:8 by aboudreault, 14 years ago

Just to be clear, the function has also been added in SWIG bindings. Unless the proper typemap is implemented for the module’s language users will not be able to pass the classgroup array parameter to this method. The method without the optional arguments is usable though.

comment:9 by sdlime, 14 years ago

Only question I would raise is whether this is better as a shapeObj or layerObj method. Instinctively I looked for the SWIG binding in shape.i and not layer.i. Advantage is that you wouldn't have to screw with passing the other arguments, the prototype would be:

  int getClassIndex(layer)

The scaledenom and classgroup stuff can all be accessed back through the layerObj.

Steve

comment:10 by aboudreault, 14 years ago

Steve, I have no objection to move this in the shape object. However, if we want to allow people to get the class index for a specific scaledenom without changing altering it's mapObj, would be useful to keep this parameter. It can be optional though. Also, the classgroup is not the "class group" of the class ... but an array built in the specific language that allows the user to get the class index from a group of classes instead of all the layer classes. Can be useful in few cases...

So, I'll move the getClassIndex from the layer to shape object and make the scaledenom parameter optional. correct ?

Note: See TracTickets for help on using tickets.