/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1