/* * mapLines.c -- * * This file defines functions that manage maplines and maplinearrays. * See the user documentation for more information. * * Copyright (c) 2004 Gordon D. Carrie. All rights reserved. * * Licensed under the Open Software License version 2.1 * * Please address questions and feedback to user0@tkgeomap.org * * @(#) $Id: mapLines.c,v 1.7 2007/06/26 21:49:30 tkgeomap Exp $ * ******************************************** * */ #include "mapLines.h" /* * Local function declaration. */ static void lnInit _ANSI_ARGS_((struct MapLn *mapLnPtr)); /* *---------------------------------------------------------------------- * * MapLnCreate -- * * This procedure creates and initializes a new geoline. * * Results: * See the user documentation. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ MapLn MapLnCreate(nPtsMax) unsigned nPtsMax; { struct MapLn *mapLnPtr; /* Return value */ mapLnPtr = (MapLn)CKALLOC(sizeof(*mapLnPtr)); lnInit(mapLnPtr); if (nPtsMax == 0) { return mapLnPtr; } mapLnPtr->pts = (MapPt *)CKALLOC(nPtsMax * sizeof(MapPt)); mapLnPtr->nPtsMax = nPtsMax; return mapLnPtr; } /* *---------------------------------------------------------------------- * * lnInit -- * * This procedure initializes a new geoline. * * Results: * None. * * Side effects: * The contents of a MapLn structure are set. The previous contents, * which are assumed to be garbage, are ignored. * *---------------------------------------------------------------------- */ static void lnInit(mapLnPtr) struct MapLn *mapLnPtr; { mapLnPtr->nPts = mapLnPtr->nPtsMax = 0; mapLnPtr->ordMax = mapLnPtr->absMax = -FLT_MAX; mapLnPtr->ordMin = mapLnPtr->absMin = FLT_MAX; mapLnPtr->pts = NULL; /* Assumes previous value is garbage */ } /* *---------------------------------------------------------------------- * * MapLnClear -- * * This procedure set the number of points in a geoline to zero without * releasing its internal storage. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnClear(mapLnPtr) struct MapLn *mapLnPtr; { /* Reset a Line without changing its memory allocation */ mapLnPtr->nPts = 0; mapLnPtr->ordMax = mapLnPtr->absMax = -FLT_MAX; mapLnPtr->ordMin = mapLnPtr->absMin = FLT_MAX; } /* *---------------------------------------------------------------------- * * MapLnDestroy -- * * This procedure frees internal storage in a MapLn structure, and * frees the structure. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnDestroy(mapLnPtr) struct MapLn *mapLnPtr; { /* Free storage associated with mapLnPtr and then free the mapLnPtr */ if (!mapLnPtr) { return; } CKFREE((char *)mapLnPtr->pts); CKFREE((char *)mapLnPtr); } /* *---------------------------------------------------------------------- * * MapLnSetAlloc -- * * This procedure changes the number of points a mapline can store. * * Results: * None. * * Side effects: * This procedure reallocates a MapLn structure's internal storage. * If the number of points is reduced, the geoline's maxima and minima * are recomputed. * *---------------------------------------------------------------------- */ void MapLnSetAlloc(mapLnPtr, nPtsMax) struct MapLn *mapLnPtr; unsigned nPtsMax; { /* * Set mapLnPtr->nPtsMax to nPtsMax. Returns 1 on success or 0 on failure * (if reallocation is required and fails). * If mapLnPtr has more points than nPtsMax, the excess points are lost. */ if (mapLnPtr->nPtsMax == nPtsMax) { return; } if (nPtsMax == 0) { CKFREE((char *)mapLnPtr->pts); lnInit(mapLnPtr); return; } mapLnPtr->pts = (MapPt *)CKREALLOC((char *)mapLnPtr->pts, nPtsMax * sizeof(MapPt)); mapLnPtr->nPtsMax = nPtsMax; if (mapLnPtr->nPts > mapLnPtr->nPtsMax) { /* * If line is shrinking, reset nPts and recompute maxima and minima. */ MapPt *p, *ep; mapLnPtr->nPts = mapLnPtr->nPtsMax; for (p = mapLnPtr->pts, ep = mapLnPtr->pts + mapLnPtr->nPts; p < ep; p++) { mapLnPtr->absMax = (mapLnPtr->absMax > p->abs) ? mapLnPtr->absMax : p->abs; mapLnPtr->absMin = (mapLnPtr->absMin < p->abs) ? mapLnPtr->absMin : p->abs; mapLnPtr->ordMax = (mapLnPtr->ordMax > p->ord) ? mapLnPtr->ordMax : p->ord; mapLnPtr->ordMin = (mapLnPtr->ordMin < p->ord) ? mapLnPtr->ordMin : p->ord; } } } /* *---------------------------------------------------------------------- * * MapLnAddPt -- * * This procedure adds a point to a mapline. * * Results: * None. * * Side effects: * The mapline's allocation might increase. It's maxima and minima will * be adjusted. * *---------------------------------------------------------------------- */ void MapLnAddPt(p, mapLnPtr) MapPt p; struct MapLn *mapLnPtr; { if (mapLnPtr->nPts + 1 > mapLnPtr->nPtsMax) { MapLnSetAlloc(mapLnPtr, ((mapLnPtr->nPtsMax + 4) * 5) / 4); } mapLnPtr->absMin = (mapLnPtr->absMin < p.abs) ? mapLnPtr->absMin : p.abs; mapLnPtr->absMax = (mapLnPtr->absMax > p.abs) ? mapLnPtr->absMax : p.abs; mapLnPtr->ordMin = (mapLnPtr->ordMin < p.ord) ? mapLnPtr->ordMin : p.ord; mapLnPtr->ordMax = (mapLnPtr->ordMax > p.ord) ? mapLnPtr->ordMax : p.ord; mapLnPtr->pts[mapLnPtr->nPts] = p; mapLnPtr->nPts++; } /* *---------------------------------------------------------------------- * * MapLnGetPt -- * * This procedure retrieve a map-point from a mapline. * * Results: * See the user documentation. * * Side effects: * None. * *---------------------------------------------------------------------- */ MapPt MapLnGetPt(mapLnPtr, n) struct MapLn *mapLnPtr; unsigned n; { return (n < mapLnPtr->nPts) ? *(mapLnPtr->pts + n) : MapPtNowhere(); } /* *---------------------------------------------------------------------- * * MapLnArrCreate -- * * This procedure creates and initializes an new maplinearray. * * Results: * See the user documentation. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ MapLnArr MapLnArrCreate(nLinesMax) unsigned nLinesMax; { struct MapLnArr *mapLnArrPtr; int n; mapLnArrPtr = (MapLnArr)CKALLOC(sizeof(*mapLnArrPtr)); mapLnArrPtr->descr = NULL; mapLnArrPtr->lines = NULL; MapLnArrSetDescr(mapLnArrPtr, ""); mapLnArrPtr->nLines = mapLnArrPtr->nLinesMax = 0; mapLnArrPtr->nPts = mapLnArrPtr->nMax = 0; mapLnArrPtr->ordMax = mapLnArrPtr->absMax = -FLT_MAX; mapLnArrPtr->ordMin = mapLnArrPtr->absMin = FLT_MAX; mapLnArrPtr->proj = NULL; if (nLinesMax == 0) { return mapLnArrPtr; } mapLnArrPtr->lines = (MapLn *)CKALLOC(nLinesMax * sizeof(MapLn)); mapLnArrPtr->nLinesMax = nLinesMax; for (n = 0; n < nLinesMax; n++) { mapLnArrPtr->lines[n] = NULL; } return mapLnArrPtr; } /* *---------------------------------------------------------------------- * * MapLnArrDestroy -- * * This procedure frees internal storage in a maplinearray and frees the * maplinearray. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrDestroy(mapLnArrPtr) struct MapLnArr *mapLnArrPtr; { int n; if ( !mapLnArrPtr ) { return; } for (n = 0; n < mapLnArrPtr->nLines; n++) { MapLnDestroy(mapLnArrPtr->lines[n]); } CKFREE((char *)mapLnArrPtr->lines); CKFREE((char *)mapLnArrPtr->descr); CKFREE((char *)mapLnArrPtr); } /* *---------------------------------------------------------------------- * * MapLnArrSetDescr -- * * This procedure sets the descriptor for a maplinearray. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrSetDescr(mapLnArrPtr, descr) struct MapLnArr *mapLnArrPtr; CONST char *descr; { mapLnArrPtr->descr = CKREALLOC(mapLnArrPtr->descr, strlen(descr) + 1); strcpy(mapLnArrPtr->descr, descr); } /* *---------------------------------------------------------------------- * * MapLnArrSetAlloc -- * * This procedure changes the number of maplines a maplinearray can store. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrSetAlloc(mapLnArrPtr, nLinesMax) struct MapLnArr *mapLnArrPtr; unsigned nLinesMax; { int n; /* Loop index */ if (mapLnArrPtr->nLinesMax == nLinesMax) { return; } /* * If number of lines decreases, free excess lines */ for (n = nLinesMax; n < mapLnArrPtr->nLinesMax; n++) { MapLnDestroy(mapLnArrPtr->lines[n]); } /* * Reallocate */ mapLnArrPtr->lines = (MapLn *)CKREALLOC((char *)mapLnArrPtr->lines, nLinesMax * sizeof(MapLn)); mapLnArrPtr->nLinesMax = nLinesMax; /* * Initialize new lines */ for (n = mapLnArrPtr->nLines; n < mapLnArrPtr->nLinesMax; n++) { mapLnArrPtr->lines[n] = NULL; } } /* *---------------------------------------------------------------------- * * MapLnArrSet -- * * This procedure is used to store the geolinearray, projection * that produced a maplinearray. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrSet(mapLnArrPtr, geoLnArr, proj) struct MapLnArr *mapLnArrPtr; GeoLnArr geoLnArr; GeoProj proj; { mapLnArrPtr->geoLnArr = geoLnArr; mapLnArrPtr->proj = proj; } /* *---------------------------------------------------------------------- * * MapLnArrAddLine -- * * This procedure copies a mapline onto the end of a maplinearray. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrAddLine(mapLnPtr, mapLnArrPtr) struct MapLn *mapLnPtr; struct MapLnArr *mapLnArrPtr; { int nLines; /* Initial number of lines in mapLnArrPtr */ /* * If mapLnArrPtr needs more space in its allocation, grow it by 25% */ nLines = mapLnArrPtr->nLines; if (nLines + 1 > mapLnArrPtr->nLinesMax) { MapLnArrSetAlloc(mapLnArrPtr, ((mapLnArrPtr->nLinesMax + 4) * 5) / 4); } /* * Update information and add copy of mapLnPtr to array */ mapLnArrPtr->lines[nLines] = MapLnCreate(mapLnPtr->nPts); mapLnArrPtr->nPts += mapLnPtr->nPts; mapLnArrPtr->nMax = (mapLnArrPtr->nMax > mapLnPtr->nPts) ? mapLnArrPtr->nMax : mapLnPtr->nPts; mapLnArrPtr->absMin = (mapLnArrPtr->absMin < mapLnPtr->absMin) ? mapLnArrPtr->absMin : mapLnPtr->absMin; mapLnArrPtr->absMax = (mapLnArrPtr->absMax > mapLnPtr->absMax) ? mapLnArrPtr->absMax : mapLnPtr->absMax; mapLnArrPtr->ordMin = (mapLnArrPtr->ordMin < mapLnPtr->ordMin) ? mapLnArrPtr->ordMin : mapLnPtr->ordMin; mapLnArrPtr->ordMax = (mapLnArrPtr->ordMax > mapLnPtr->ordMax) ? mapLnArrPtr->ordMax : mapLnPtr->ordMax; memcpy(mapLnArrPtr->lines[nLines]->pts, mapLnPtr->pts, mapLnPtr->nPts * sizeof(MapPt)); mapLnArrPtr->lines[nLines]->nPts = mapLnPtr->nPts; mapLnArrPtr->lines[nLines]->absMin = mapLnPtr->absMin; mapLnArrPtr->lines[nLines]->absMax = mapLnPtr->absMax; mapLnArrPtr->lines[nLines]->ordMin = mapLnPtr->ordMin; mapLnArrPtr->lines[nLines]->ordMax = mapLnPtr->ordMax; mapLnArrPtr->nLines++; } /* *---------------------------------------------------------------------- * * MapLnArrPutLine -- * * This procedure gives a mapline to a maplinearray. * * Results: * None. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ void MapLnArrPutLine(mapLnPtr, mapLnArrPtr) MapLn mapLnPtr; struct MapLnArr *mapLnArrPtr; { int nLines; /* Initial number of lines in mapLnArrPtr */ /* * If mapLnArrPtr needs more space in its allocation, grow it by 25% */ nLines = mapLnArrPtr->nLines; if (nLines + 1 > mapLnArrPtr->nLinesMax) { MapLnArrSetAlloc(mapLnArrPtr, ((mapLnArrPtr->nLinesMax + 4) * 5) / 4); } /* * Update information and add the line to the array */ mapLnArrPtr->nPts += mapLnPtr->nPts; mapLnArrPtr->nMax = (mapLnArrPtr->nMax > mapLnPtr->nPts) ? mapLnArrPtr->nMax : mapLnPtr->nPts; mapLnArrPtr->absMin = (mapLnArrPtr->absMin < mapLnPtr->absMin) ? mapLnArrPtr->absMin : mapLnPtr->absMin; mapLnArrPtr->absMax = (mapLnArrPtr->absMax > mapLnPtr->absMax) ? mapLnArrPtr->absMax : mapLnPtr->absMax; mapLnArrPtr->ordMin = (mapLnArrPtr->ordMin < mapLnPtr->ordMin) ? mapLnArrPtr->ordMin : mapLnPtr->ordMin; mapLnArrPtr->ordMax = (mapLnArrPtr->ordMax > mapLnPtr->ordMax) ? mapLnArrPtr->ordMax : mapLnPtr->ordMax; mapLnArrPtr->lines[nLines] = mapLnPtr; mapLnArrPtr->nLines++; } /* *---------------------------------------------------------------------- * * MapLnArrGetDescr -- * * This is a member access function. * * Results: * See the user documentation. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * MapLnArrGetDescr(mapLnArrPtr) struct MapLnArr *mapLnArrPtr; { return mapLnArrPtr->descr; } /* *---------------------------------------------------------------------- * * MapLnArrGetLine -- * * This procedure retrieves a mapline from a maplinearray. * * Results: * See the user documentation. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ MapLn MapLnArrGetLine(mapLnArrPtr, n) struct MapLnArr *mapLnArrPtr; unsigned n; { return (n < mapLnArrPtr->nLines) ? mapLnArrPtr->lines[n] : NULL; }