Adds link vertex get/set functions to the API

This commit is contained in:
Lew Rossman
2019-10-29 16:33:40 -04:00
parent d5becaf1a0
commit 7aadc83ddf
15 changed files with 297 additions and 32 deletions

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/26/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -3985,17 +3985,17 @@ int DLLEXPORT EN_setlinkvalue(EN_Project p, int index, int property, double valu
int DLLEXPORT EN_setpipedata(EN_Project p, int index, double length,
double diam, double rough, double mloss)
/*----------------------------------------------------------------
** Input: index = pipe link index
** length = pipe length
** diam = pipe diameter
** rough = pipe roughness coefficient
** mloss = minor loss coefficient
** Output: none
** Returns: error code
** Purpose: sets several properties for a pipe link
**----------------------------------------------------------------
*/
/*----------------------------------------------------------------
** Input: index = pipe link index
** length = pipe length
** diam = pipe diameter
** rough = pipe roughness coefficient
** mloss = minor loss coefficient
** Output: none
** Returns: error code
** Purpose: sets several properties for a pipe link
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
@@ -4024,6 +4024,96 @@ int DLLEXPORT EN_setpipedata(EN_Project p, int index, double length,
return 0;
}
int DLLEXPORT EN_getvertexcount(EN_Project p, int index, int *count)
/*----------------------------------------------------------------
** Input: index = link index
** Output: count = number of link's vertex points
** Returns: error code
** Purpose: retrieves number of vertex points in a link
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
Slink *Link = net->Link;
Pvertices vertices;
// Check that link exists
*count = 0;
if (!p->Openflag) return 102;
if (index <= 0 || index > net->Nlinks) return 204;
// Set count to number of vertices
vertices = Link[index].Vertices;
if (vertices) *count = vertices->Npts;
return 0;
}
int DLLEXPORT EN_getvertex(EN_Project p, int index, int vertex, double *x, double *y)
/*----------------------------------------------------------------
** Input: index = link index
** vertex = index of a link vertex point
** Output: x = vertex point's X-coordinate
** y = vertex point's Y-coordinate
** Returns: error code
** Purpose: retrieves the coordinates of a vertex point in a link
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
Slink *Link = net->Link;
Pvertices vertices;
// Check that link exists
*x = MISSING;
*y = MISSING;
if (!p->Openflag) return 102;
if (index <= 0 || index > net->Nlinks) return 204;
// Check that vertex exists
vertices = Link[index].Vertices;
if (vertices == NULL) return 255;
if (vertex <= 0 || vertex > vertices->Npts) return 255;
*x = vertices->X[vertex - 1];
*y = vertices->Y[vertex - 1];
return 0;
}
int DLLEXPORT EN_setvertices(EN_Project p, int index, double *x, double *y, int count)
/*----------------------------------------------------------------
** Input: index = link index
** x = array of X-coordinates for vertex points
** y = array of Y-coordinates for vertex points
** count = number of vertex points
** Returns: error code
** Purpose: assigns a set of vertex points to a link
**----------------------------------------------------------------
*/
{
Network *net = &p->network;
Slink *link;
int i;
int err = 0;
// Check that link exists
if (!p->Openflag) return 102;
if (index <= 0 || index > net->Nlinks) return 204;
link = &net->Link[index];
// Delete existing set of vertices
freelinkvertices(link);
// Add each new vertex to the link
for (i = 0; i < count; i++)
{
err = addlinkvertex(link, x[i], y[i]);
if (err) break;
}
if (err) freelinkvertices(link);
return err;
}
/********************************************************************

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/26/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -512,6 +512,20 @@ int DLLEXPORT ENsetpipedata(int index, EN_API_FLOAT_TYPE length,
return EN_setpipedata(_defaultProject, index, length, diam, rough, mloss);
}
int DLLEXPORT ENgetvertexcount(int index, int *count)
{
return EN_getvertexcount(_defaultProject, index, count);
}
int DLLEXPORT ENgetvertex(int index, int vertex, double *x, double *y)
{
return EN_getvertex(_defaultProject, index, vertex, x, y);
}
int DLLEXPORT ENsetvertices(int index, double *x, double *y, int count)
{
return EN_setvertices(_defaultProject, index, x, y, count);
}
/********************************************************************

View File

@@ -53,6 +53,7 @@ DAT(251,"invalid parameter code")
DAT(252,"invalid ID name")
DAT(253,"nonexistent demand category")
DAT(254,"node with no coordinates")
DAT(255,"invalid link vertex")
DAT(257,"nonexistent rule")
DAT(258,"nonexistent rule clause")
DAT(259,"attempt to delete a node that still has links connected to it")

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 07/08/2019
Last Updated: 10/29/2019
******************************************************************************
*/
#ifndef FUNCS_H
@@ -41,6 +41,9 @@ Pdemand finddemand(Pdemand, int);
int adddemand(Snode *, double, int, char *);
void freedemands(Snode *);
int addlinkvertex(Slink *, double, double);
void freelinkvertices(Slink *);
void adjustpatterns(Network *, int);
void adjustcurves(Network *, int);
int resizecurve(Scurve *, int);
@@ -101,6 +104,7 @@ int statusdata(Project *);
int reportdata(Project *);
int timedata(Project *);
int optiondata(Project *);
int vertexdata(Project *);
// ------- RULES.C ------------------

View File

@@ -7,7 +7,7 @@ Description: saves network data to an EPANET formatted text file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 05/15/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -76,7 +76,6 @@ void saveauxdata(Project *pr, FILE *f)
// Write section heading to file
switch (sect)
{
case _VERTICES:
case _LABELS:
case _BACKDROP:
case _TAGS:
@@ -91,8 +90,6 @@ void saveauxdata(Project *pr, FILE *f)
write = FALSE;
switch (sect)
{
case _VERTICES:
if (findlink(&pr->network, tok) || *tok == ';') write = TRUE; break;
case _TAGS:
if (*tok == ';' ||
(match("NODE", tok) && findnode(&pr->network, strtok(NULL, SEPSTR))) ||
@@ -788,6 +785,20 @@ int saveinpfile(Project *pr, const char *fname)
fprintf(f, "\n %-31s %14.6f %14.6f", node->ID, node->X, node->Y);
}
// Write [VERTICES] section
fprintf(f, "\n\n");
fprintf(f, s_VERTICES);
for (i = 1; i <= net->Nlinks; i++)
{
link = &net->Link[i];
if (link->Vertices != NULL)
{
for (j = 0; j < link->Vertices->Npts; j++)
fprintf(f, "\n %-31s %14.6f %14.6f",
link->ID, link->Vertices->X[j], link->Vertices->Y[j]);
}
}
// Save auxilary data to new input file
fprintf(f, "\n");
saveauxdata(pr, f);

View File

@@ -7,7 +7,7 @@ Description: reads and interprets network data from an EPANET input file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 05/15/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -330,11 +330,11 @@ int newline(Project *pr, int sect, char *line)
case _TIMES: return (timedata(pr));
case _OPTIONS: return (optiondata(pr));
case _COORDS: return (coordata(pr));
case _VERTICES: return (vertexdata(pr));
// Data in these sections are not used for any computations
case _LABELS:
case _TAGS:
case _VERTICES:
case _BACKDROP:
return (0);
}

View File

@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/26/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -716,6 +716,37 @@ int coordata(Project *pr)
return 0;
}
int vertexdata(Project *pr)
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: processes link vertex data
** Format:
** [VERTICES]
** id x y
**--------------------------------------------------------------
*/
{
Network *net = &pr->network;
Parser *parser = &pr->parser;
int j;
double x, y;
// Check for valid link ID
if (parser->Ntokens < 3) return 201;
if ((j = findlink(net, parser->Tok[0])) == 0) return setError(parser, 0, 204);
// Check for valid coordinate data
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
if (!getfloat(parser->Tok[2], &y)) return setError(parser, 2, 202);
// Add to link's list of vertex points
return addlinkvertex(&net->Link[j], x, y);
}
int demanddata(Project *pr)
/*
**--------------------------------------------------------------

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/26/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -18,8 +18,6 @@
//*** For the Windows SDK _tempnam function ***//
#ifdef _WIN32
#include <windows.h>
//#else
//#include <unistd.h >
#endif
#include "types.h"
@@ -363,6 +361,7 @@ int allocdata(Project *pr)
}
for (n = 0; n <= pr->parser.MaxLinks; n++)
{
pr->network.Link[n].Vertices = NULL;
pr->network.Link[n].Comment = NULL;
}
}
@@ -409,8 +408,9 @@ void freedata(Project *pr)
// Free memory for link data
if (pr->network.Link != NULL)
{
for (j = 0; j <= pr->parser.MaxLinks; j++)
for (j = 1; j <= pr->parser.MaxLinks; j++)
{
freelinkvertices(&pr->network.Link[j]);
free(pr->network.Link[j].Comment);
}
}
@@ -538,6 +538,61 @@ void freedemands(Snode *node)
node->D = NULL;
}
int addlinkvertex(Slink *link, double x, double y)
/*----------------------------------------------------------------
** Input: link = pointer to a network link
** x = x-coordinate of a new vertex
** y = y-coordiante of a new vertex
** Returns: an error code
** Purpose: adds to a link's collection of vertex points.
**----------------------------------------------------------------
*/
{
static int CHUNKSIZE = 5;
int n;
Pvertices vertices;
if (link->Vertices == NULL)
{
vertices = (struct Svertices *) malloc(sizeof(struct Svertices));
if (vertices == NULL) return 101;
vertices->Npts = 0;
vertices->Capacity = CHUNKSIZE;
vertices->X = (double *) calloc(vertices->Capacity, sizeof(double));
vertices->Y = (double *) calloc(vertices->Capacity, sizeof(double));
link->Vertices = vertices;
}
vertices = link->Vertices;
if (vertices->Npts >= vertices->Capacity)
{
vertices->Capacity += CHUNKSIZE;
vertices->X = realloc(vertices->X, vertices->Capacity * sizeof(double));
vertices->Y = realloc(vertices->Y, vertices->Capacity * sizeof(double));
}
if (vertices->X == NULL || vertices->Y == NULL) return 101;
n = vertices->Npts;
vertices->X[n] = x;
vertices->Y[n] = y;
vertices->Npts++;
return 0;
}
void freelinkvertices(Slink *link)
/*----------------------------------------------------------------
** Input: vertices = list of link vertex points
** Output: none
** Purpose: frees the memory used for a link's list of vertices.
**----------------------------------------------------------------
*/
{
if (link->Vertices)
{
free(link->Vertices->X);
free(link->Vertices->Y);
free(link->Vertices);
link->Vertices = NULL;
}
}
int buildadjlists(Network *net)
/*
**--------------------------------------------------------------

View File

@@ -7,7 +7,7 @@
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 10/26/2019
Last Updated: 10/29/2019
******************************************************************************
*/
@@ -366,6 +366,15 @@ struct Ssource // Water Quality Source Object
};
typedef struct Ssource *Psource; // Pointer to source object
struct Svertices // Coordinates of a link's vertices
{
double *X; // array of x-coordinates
double *Y; // array of y-coordinates
int Npts; // number of vertex points
int Capacity; // capacity of coordinate arrays
};
typedef struct Svertices *Pvertices; // Pointer to a link's vertices
typedef struct // Node Object
{
char ID[MAXID+1]; // node ID
@@ -397,6 +406,7 @@ typedef struct // Link Object
double Rc; // reaction coeff.
LinkType Type; // link type
StatusType Status; // initial status
Pvertices Vertices; // internal vertex coordinates
int Rpt; // reporting flag
int ResultIndex; // saved result index
char *Comment; // link comment