Skip to content

Commit

Permalink
Enhancing the symbol and symbolset functionality as requesting in Map…
Browse files Browse the repository at this point in the history
…server bug 579. We're doing this in the same way as we are now doing multiple styles with classes. Symbols can exist on their own and so can SymbolSets. See mapscript.txt for the new API. Am trying to keep in mind the existing implementation in PHP-Mapscript, but have to break compatibility a bit since that one is more limited.

git-svn-id: http://svn.osgeo.org/mapserver/trunk@2850 7532c77e-422f-0410-93f4-f0b67bdd69e2
  • Loading branch information
sgillies committed Mar 9, 2004
1 parent 26529dd commit 29eef6e
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 19 deletions.
61 changes: 59 additions & 2 deletions mapscript/doc/mapscript.txt
Expand Up @@ -1013,13 +1013,70 @@ Methods
.. _new styleObj:

new styleObj() : styleObj_
Returns new instance.
Returns new default style Obj instance.


-----------------------------------------------------------------------------
symbolObj
-----------------------------------------------------------------------------

A symbolObj is associated with one symbolSetObj_.

::

+--------+ 0..* 1 +-----------+
| Symbol | <-------- | SymbolSet |
+--------+ +-----------+

A styleObj_ will often refer to a symbolObj by name or index, but this is
not really an object association, is it?

Methods
-------

**TODO**

new symbolObj(string name) : symbolObj_
Create new default symbol named *name*.


-----------------------------------------------------------------------------
symbolSetObj
-----------------------------------------------------------------------------

x
A symbolSetObj is an attribute of a mapObj_ and is associated with instances
of symbolObj_.

::

+-----------+ 1 0..* +--------+
| SymbolSet | --------> | Symbol |
+-----------+ +--------+

Attributes
----------

numsymbols : int immutable
Number of symbols in the set.

Methods
-------

new symbolSetObj([string symbolfile]) : symbolSetObj_
Create new instance. If *symbolfile* is specified, symbols will be
loaded from the file.

appendSymbol(symbolObj_ symbol) : int
Add a copy of *symbol* to the symbolset and return its index.

getSymbol(int index) : symbolObj_
Returns a reference to the symbol at *index*.

getSymbolByName(string name) : symbolObj_
Returns a reference to the symbol named *name*.

removeSymbol(int index) : symbolObj_
Remove the symbol at *index* and return a copy of the symbol.


.. [1] This **really** needs to be changed in the future. In fact a layer
Expand Down
81 changes: 66 additions & 15 deletions mapscript/mapscript.i
Expand Up @@ -617,25 +617,76 @@ memory.") const char * {
}
}

/* Full support for symbols and addition of them to the map symbolset
* is done to resolve MapServer bug 579
* http://mapserver.gis.umn.edu/bugs/show_bug.cgi?id=579 */

%extend symbolObj {
symbolObj(char *name) {
symbolObj *symbol;
symbol = (symbolObj *) malloc(sizeof(symbolObj));
initSymbol(symbol);
symbol->name = strdup(name);
return symbol;
}

~symbolObj() {
if (self->name) free(self->name);
if (self->img) gdImageDestroy(self->img);
if (self->font) free(self->font);
if (self->imagepath) free(self->imagepath);
}
}

%extend symbolSetObj {
symbolObj *getSymbol(int i) {
if(i >= 0 && i < self->numsymbols)
return (symbolObj *) &(self->symbol[i]);
else
return NULL;
}

symbolObj *getSymbolByName(char *name) {
int i;
symbolSetObj(const char *symbolfile=NULL) {
symbolSetObj *symbolset;
mapObj *temp_map=NULL;
symbolset = (symbolSetObj *) malloc(sizeof(symbolSetObj));
msInitSymbolSet(symbolset);
if (symbolfile) {
symbolset->filename = strdup(symbolfile);
temp_map = msNewMapObj();
msLoadSymbolSet(symbolset, temp_map);
symbolset->map = NULL;
msFreeMap(temp_map);
}
return symbolset;
}

~symbolSetObj() {
msFreeSymbolSet(self);
}

if(!name) return NULL;
symbolObj *getSymbol(int i) {
if(i >= 0 && i < self->numsymbols)
return (symbolObj *) &(self->symbol[i]);
else
return NULL;
}

symbolObj *getSymbolByName(char *name) {
int i;

if (!name) return NULL;

i = msGetSymbolIndex(self, name);
if (i == -1)
return NULL; // no such symbol
else
return (symbolObj *) &(self->symbol[i]);
}

int appendSymbol(symbolObj *symbol) {
return msAppendSymbol(self, symbol);
}

%newobject removeSymbol;
symbolObj *removeSymbol(int index) {
return msRemoveSymbol(self, index);
}

i = msGetSymbolIndex(self, name);
if(i == -1)
return NULL; // no such symbol
else
return (symbolObj *) &(self->symbol[i]);
}
}

//
Expand Down
50 changes: 48 additions & 2 deletions mapscript/python/tests/testMapScript.py
Expand Up @@ -120,6 +120,27 @@ def testRemoveClass2ClassName(self):
self.mapobj1.getLayer(0).removeClass(1)
assert self.mapobj1.getLayer(0).getClass(0).name == c1name

# symbol tests
class SymbolTestCase(unittest.TestCase):
def setUp(self):
self.mapobj1 = mapscript.mapObj(testMapfile)
def tearDown(self):
self.mapobj1 = None
def testConstructor(self):
symbol = mapscript.symbolObj('test')
assert symbol.name == 'test'
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

# symbolset tests
class SymbolSetTestCase(unittest.TestCase):
def setUp(self):
Expand All @@ -129,15 +150,40 @@ def tearDown(self):
def testGetNumSymbols(self):
num = self.mapobj1.getNumSymbols()
assert num == 2, num
def testSymbolsetNumsymbols(self):
def testSymbolSetNumsymbols(self):
num = self.mapobj1.symbolset.numsymbols
assert num == 2, num
def testSymbolsetSymbolNames(self):
def testSymbolSetSymbolNames(self):
set = self.mapobj1.symbolset
names = [None, 'line', 'tie']
for i in range(set.numsymbols):
symbol = set.getSymbol(i)
assert symbol.name == names[i], symbol.name
def testConstructorNoArgs(self):
symbolset = mapscript.symbolSetObj()
num = symbolset.numsymbols
assert num == 1, num
def testConstructorFile(self):
symbolset = mapscript.SymbolSet('../../tests/symbols.txt')
num = symbolset.numsymbols
assert num == 2, num
def testAddSymbolToNewSymbolSet(self):
symbolset = mapscript.SymbolSet('../../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.SymbolSet('../../tests/symbols.txt')
symbolset.removeSymbol(1)
num = symbolset.numsymbols
assert num == 1, num

# fontset tests
class FontSetTestCase(unittest.TestCase):
Expand Down
40 changes: 40 additions & 0 deletions mapsymbol.c
Expand Up @@ -595,3 +595,43 @@ int msAddNewSymbol(mapObj *map, char *name)
return i;
}

/* msAppendSymbol and msRemoveSymbol are part of the work to resolve
* MapServer bug 579.
* http://mapserver.gis.umn.edu/bugs/show_bug.cgi?id=579 */


int msAppendSymbol(symbolSetObj *symbolset, symbolObj *symbol) {
// Possible to add another symbol?
if (symbolset->numsymbols == MS_MAXSYMBOLS) {
msSetError(MS_CHILDERR, "Maximum number of symbols, %d, has been reached", "msAppendSymbol()", MS_MAXSYMBOLS);
return -1;
}
symbolset->numsymbols++;
msCopySymbol(&(symbolset->symbol[symbolset->numsymbols-1]), symbol);
return symbolset->numsymbols;
}


symbolObj *msRemoveSymbol(symbolSetObj *symbolset, int nSymbolIndex) {
int i;
symbolObj *symbol;
if (symbolset->numsymbols == 1) {
msSetError(MS_CHILDERR, "Cannot remove a symbolset's sole symbol", "removeSymbol()");
return NULL;
}
else if (nSymbolIndex < 0 || nSymbolIndex >= symbolset->numsymbols) {
msSetError(MS_CHILDERR, "Cannot remove symbol, invalid nSymbolIndex %d", "removeSymbol()", nSymbolIndex);
return NULL;
}
else {
symbol = (symbolObj *)malloc(sizeof(symbolObj));
msCopySymbol(symbol, &(symbolset->symbol[nSymbolIndex]));
for (i=nSymbolIndex+1; i<symbolset->numsymbols; i++) {
symbolset->symbol[i-1] = symbolset->symbol[i];
}
symbolset->numsymbols--;
return symbol;
}
}


0 comments on commit 29eef6e

Please sign in to comment.