Opened 20 years ago

Closed 20 years ago

#579 closed enhancement (fixed)

[FR] Dynamic Symbol creation/add/remove

Reported by: romain@… Owned by: sdlime
Priority: high Milestone:
Component: MapScript Version: 4.0
Severity: minor Keywords:
Cc: sgillies@…

Description

Mapscript should support complete handling of symbols set.

The main idea is to repeat the same concept as the mapObj.

If we instanciate a symbolSetObj with an empty string, we have an empty symbolSet.

symbolSetObj = mapscript.symbolSetObj('')
# here we could this
symbolObj = mapscript.symbolObj()

# we define the symbolObj objet.
...
# and then add it to the symbolSet
index = symbolSetObj.add(symbol)

if we want to remove it:
symbolSetObj.remove(index) or symbolSetObj.removeByName('name')

After all:
symbolSetObj.save(path)

The main thinking is how to handle the fact that we can define symbol in the
MapFile or in a symbolSet file.

We could use:

symbolSet.symbolFile

This attribute would be filled automaticaly when we do a save(), or manualy.

If it is set, mapObj.save() would save data and call mapObj.symbolSet.save()
Thanks.

Change History (10)

comment:1 by romain@…, 20 years ago

*** Bug 578 has been marked as a duplicate of this bug. ***

comment:2 by dmorissette, 20 years ago

Cc: sgillies@… mapserver-bugs@… added

comment:3 by sgillies@…, 20 years ago

Status: newassigned
I'll pick this one up.

comment:4 by sgillies@…, 20 years ago

Romain, it took me a little time to appreciate your request for a SymbolSet
outside of a map.  I agree that it will be useful and I am trying to make
it work out.

Update on the work so far ... new features can be summarized like this
(a few lines from the mapscript unit tests):

    def testAddSymbolToMapSymbolSet(self):
        symbola = mapscript.symbolObj('testa')
        symbolb = mapscript.symbolObj('testb')
        self.mapobj1.symbolset.appendSymbol(symbola) 
        self.mapobj1.symbolset.appendSymbol(symbolb) 
        num = self.mapobj1.symbolset.numsymbols
        assert num == 4, num
    def testRemoveSymbolFromMapSymbolSet(self):
        self.mapobj1.symbolset.removeSymbol(1)
        num = self.mapobj1.symbolset.numsymbols
        assert num == 1, num

    def testAddSymbolToNewSymbolSet(self):
        symbolset = mapscript.symbolSetObj('../../tests/symbols.txt')
        symbola = mapscript.symbolObj('testa')
        symbolb = mapscript.symbolObj('testb')
        symbolset.appendSymbol(symbola) 
        symbolset.appendSymbol(symbolb) 
        num = symbolset.numsymbols
        assert num == 4, num
        names = [None, 'line', 'testa', 'testb']
        for i in range(symbolset.numsymbols):
            symbol = symbolset.getSymbol(i)
            assert symbol.name == names[i], symbol.name
    def testRemoveSymbolFromNewSymbolSet(self):
        symbolset = mapscript.symbolSetObj('../../tests/symbols.txt')
        symbolset.removeSymbol(1)
        num = symbolset.numsymbols
        assert num == 1, num

Steve Lime requested that I follow the PHP-Mapscript version, but we have
to diverge just a bit.  A Symbol should be able to be constructed outside
the context of a mapObj and so we are removing the mapObj from the 
constructor args.  Instead we do

   symbol = mapscript.symbolObj('new_symbol')
   new_symbol_index = a_map.symbolset.appendSymbol(symbol)

comment:5 by sgillies@…, 20 years ago

Another update.

Have added a symbolSetObj.save() method.  Works like all the other
class save methods, writes a symbolset to a file.

Have added symbol.getPoints() and symbol.setPoints().  These 
return lineObj and take lineObj as a parameter respectively.

For example:

    def testGetPoints(self):
        symbol = self.mapobj1.symbolset.getSymbol(1)
        assert symbol.name == 'line'
        line = symbol.getPoints()
        assert line.numpoints == 1, line.numpoints
        pt = line.get(0)
        assert pt.x == 1.0, pt.x
        assert pt.y == 1.0, pt.y
    def testSetPoints(self):
        symbol = self.mapobj1.symbolset.getSymbol(1)
        assert symbol.name == 'line'
        line = mapscript.lineObj()
        line.add(mapscript.pointObj(2.0, 2.0))
        line.add(mapscript.pointObj(3.0, 3.0))
        assert symbol.setPoints(line) == 2
        line = symbol.getPoints()
        assert line.numpoints == 2, line.numpoints
        pt = line.get(1)
        assert pt.x == 3.0, pt.x
        assert pt.y == 3.0, pt.y

The PHP-Mapscript version of these methods accept or returns arrays.  
This implementation is problematic for SWIG and it seems more natural
to use an existing mapscript class, lineObj, rather than arrays.

Pixmap symbol support is coming up.

comment:6 by sgillies@…, 20 years ago

Last update.

The symbolObj constructor now allows creation of pixmap symbols.

A setStyle method allows users to set the symbol dashing style:

symbol.setStyle(0, 4)
symbol.setStyle(1, 2)
symbol.numstyles = 2

produces the same results as

SYMBOL
  STYLE 4 2 END
END

Users will for the present have to explicitly set numstyles
when altering the symbol styles in this way.

I haven't done much to support anything other than vector,
ellipse, and pixmap symbols.  MapServer's symbolObj is confusing
and overloaded, could use some refactoring in the future perhaps.


comment:7 by sdlime, 20 years ago

We really should try to keep the versions together. The PHP folks can change
their stuff too...

comment:8 by sgillies@…, 20 years ago

Yeah, I want mapscript to be one interface too ...

and if, like DM Solutions, I was supporting one language
I'd just write the Python typemaps and we'd have getPoints
and setPoints using Python lists.  But I need to write code
that will work with Perl, Python, Ruby, Java, C# (maybe),
and other languages supported by SWIG.

Except for the fact that using a lineObj for symbol points
is clearly the natural thing to do.

We'll work it out and try to get it together before the next
release.  I think the PHP folks will like my stuff if they
take a look.  


comment:9 by assefa, 20 years ago

I will check the SWIG api carfully and modify the PHP version to conform to
this. I do not mind at this point to modifying the PHP version for conformace
since this functionnality is new. It might break existing applications but
better do it now than latter.

I think that the next time I add some stuff like this the the mapscript,  I
would discuss the api a bit with you guys so that it fits all the mapscript flavors.

comment:10 by sgillies@…, 20 years ago

Resolution: fixed
Status: assignedclosed
Was just holding this open for feedback from mapserver-bugs@dmsolutions.ca
and am now closing it.


Note: See TracTickets for help on using tickets.