Exemplo n.º 1
0
/* Destroys Natural Neighbours hashing point interpolation.
 *
 * @param nn Structure to be destroyed
 */
void nnhpi_destroy(nnhpi* nn)
{
    ht_destroy(nn->ht_data);
    ht_process(nn->ht_weights, free_nn_weights);
    ht_destroy(nn->ht_weights);
    nnpi_destroy(nn->nnpi);
}
Exemplo n.º 2
0
/* Performs Natural Neighbours interpolation for an array of points.
 *
 * @param nin Number of input points
 * @param pin Array of input points [pin]
 * @param wmin Minimal allowed weight
 * @param nout Number of output points
 * @param pout Array of output points [nout]
 */
void nnpi_interpolate_points(int nin, point pin[], double wmin, int nout, point pout[])
{
    delaunay* d = delaunay_build(nin, pin, 0, NULL, 0, NULL);
    nnpi* nn = nnpi_create(d);
    int seed = 0;
    int i;

    nnpi_setwmin(nn, wmin);

    if (nn_verbose) {
        fprintf(stderr, "xytoi:\n");
        for (i = 0; i < nout; ++i) {
            point* p = &pout[i];

            fprintf(stderr, "(%.7g,%.7g) -> %d\n", p->x, p->y, delaunay_xytoi(d, p, seed));
        }
    }

    for (i = 0; i < nout; ++i)
        nnpi_interpolate_point(nn, &pout[i]);

    if (nn_verbose) {
        fprintf(stderr, "output:\n");
        for (i = 0; i < nout; ++i) {
            point* p = &pout[i];

            fprintf(stderr, "  %d:%15.7g %15.7g %15.7g\n", i, p->x, p->y, p->z);
        }
    }

    nnpi_destroy(nn);
    delaunay_destroy(d);
}
Exemplo n.º 3
0
/* Builds Natural Neighbours array interpolator. This includes calculation of
 * weights used in nnai_interpolate().
 *
 * @param d Delaunay triangulation
 * @return Natural Neighbours interpolation
 */
nnai* nnai_build(delaunay* d, long n, double* x, double* y)
{
    nnai* nn = (nnai *)malloc(sizeof(nnai));
    nnpi* nnpi = nnpi_create(d);
    int* vertices;
    double* weights;
    int i;

    if (n <= 0)
        nn_quit("nnai_create(): n = %d\n", n);

    nn->d = d;
    nn->n = n;
    nn->x = (double *)malloc(n * sizeof(double));
    memcpy(nn->x, x, n * sizeof(double));
    nn->y = (double *)malloc(n * sizeof(double));
    memcpy(nn->y, y, n * sizeof(double));
    nn->weights = (nn_weights *)malloc(n * sizeof(nn_weights));

    for (i = 0; i < n; ++i) {
        nn_weights* w = &nn->weights[i];
        point p;

        p.x = x[i];
        p.y = y[i];

        nnpi_reset(nnpi);
        nnpi_set_point(nnpi, &p);
        nnpi_calculate_weights(nnpi);
        nnpi_normalize_weights(nnpi);

        vertices = nnpi_get_vertices(nnpi);
        weights = nnpi_get_weights(nnpi);

        w->nvertices = nnpi_get_nvertices(nnpi);
        w->vertices = (int *)malloc(w->nvertices * sizeof(int));
        memcpy(w->vertices, vertices, w->nvertices * sizeof(int));
        w->weights = (double *)malloc(w->nvertices * sizeof(double));
        memcpy(w->weights, weights, w->nvertices * sizeof(double));
    }

    nnpi_destroy(nnpi);

    return nn;
}
Exemplo n.º 4
0
/* A version of nnbathy that interpolates output points serially. Can save a
 * bit of memory for large output grids.
 */
int main(int argc, char* argv[])
{
    specs* s = specs_create();
    int nin = 0;
    point* pin = NULL;
    minell* me = NULL;
    point* pout = NULL;
    double k = NaN;
    preader* pr = NULL;
    delaunay* d = NULL;
    void* interpolator = NULL;
    int ndone = 0;

    parse_commandline(argc, argv, s);

    if (s->fin == NULL)
        quit("no input data\n");

    if (!s->generate_points && s->fout == NULL && !s->nointerp)
        quit("no output grid specified\n");

    points_read(s->fin, 3, &nin, &pin);

    if (nin < 3)
        return 0;

    if (s->thin == 1)
        points_thingrid(&nin, &pin, s->nxd, s->nyd);
    else if (s->thin == 2)
        points_thinlin(&nin, &pin, s->rmax);

    if (s->nointerp) {
        points_write(nin, pin);
        specs_destroy(s);
        free(pin);
        return 0;
    }

    if (s->generate_points) {
        points_getrange(nin, pin, s->zoom, &s->xmin, &s->xmax, &s->ymin, &s->ymax);
        pr = preader_create1(s->xmin, s->xmax, s->ymin, s->ymax, s->nx, s->ny);
    } else
        pr = preader_create2(s->fout);

    if (s->invariant) {
        me = minell_build(nin, pin);
        minell_scalepoints(me, nin, pin);
    } else if (s->square)
        k = points_scaletosquare(nin, pin);

    d = delaunay_build(nin, pin, 0, NULL, 0, NULL);

    if (s->linear)
        interpolator = lpi_build(d);
    else {
        interpolator = nnpi_create(d);
        nnpi_setwmin(interpolator, s->wmin);
    }

    while ((pout = preader_getpoint(pr)) != NULL) {
        if (s->invariant)
            minell_scalepoints(me, 1, pout);
        else if (s->square)
            points_scale(1, pout, k);

        if (s->linear)
            lpi_interpolate_point(interpolator, pout);
        else
            nnpi_interpolate_point(interpolator, pout);

        if (s->invariant)
            minell_rescalepoints(me, 1, pout);
        else if (s->square)
            points_scale(1, pout, 1.0 / k);

        points_write(1, pout);
        ndone++;

        if (s->npoints > 0)
            fprintf(stderr, "  %5.2f%% done\r", 100.0 * ndone / s->npoints);
    }
    if (s->npoints > 0)
        fprintf(stderr, "                \r");

    if (me != NULL)
        minell_destroy(me);
    if (s->linear)
        lpi_destroy(interpolator);
    else
        nnpi_destroy(interpolator);
    delaunay_destroy(d);
    preader_destroy(pr);
    specs_destroy(s);
    free(pin);

    return 0;
}
NaturalNeigbourInterpolation::~NaturalNeigbourInterpolation()
{
    nnpi_destroy(interpolator_);
    delaunay_destroy(delaunay_);
}
Exemplo n.º 6
0
int main(int argc, char* argv[])
{
    char* bathyfname = NULL;
    int nbathy = -1;
    point* pbathy = NULL;

    char* gridfname = NULL;
    NODETYPE nt = NT_DD;
    gridnodes* gn = NULL;
    gridmap* gm = NULL;

    char* maskfname = NULL;
    int** mask = NULL;

    int ppe = PPE_DEF;
    double zmin = ZMIN_DEF;
    double zmax = ZMAX_DEF;

    delaunay* d = NULL;

    void (*interpolate_point) (void*, point *) = NULL;
    void* interpolator = NULL;

    int i = -1, j = -1;

    parse_commandline(argc, argv, &bathyfname, &gridfname, &maskfname, &nt, &ppe, &zmin, &zmax, &i, &j);

    /*
     * sanity check 
     */
    if (bathyfname == NULL)
        quit("no input bathymetry data specified");
    if (gridfname == NULL)
        quit("no input grid data specified");
    if (ppe <= 0 || ppe > PPE_MAX)
        quit("number of points per edge specified = %d greater than %d", ppe, PPE_MAX);
    if (zmin >= zmax)
        quit("min depth = %.3g > max depth = %.3g", zmin, zmax);
    if (nt != NT_DD && nt != NT_COR)
        quit("unsupported node type");

    /*
     * read bathymetry 
     */
    points_read(bathyfname, 3, &nbathy, &pbathy);

    if (gu_verbose)
        fprintf(stderr, "## %d input bathymetry values", nbathy);
    if (nbathy < 3)
        quit("less than 3 input bathymetry values");

    /*
     * read and validate grid 
     */
    gn = gridnodes_read(gridfname, nt);
    gridnodes_validate(gn);
    /*
     * read mask
     */
    if (maskfname != NULL) {
        int nx = gridnodes_getnce1(gn);
        int ny = gridnodes_getnce2(gn);

        mask = gu_readmask(maskfname, nx, ny);
    }
    /*
     * transform grid nodes to corner type 
     */
    if (nt != NT_COR) {
        gridnodes* newgn = gridnodes_transform(gn, NT_COR);

        gridnodes_destroy(gn);
        gn = newgn;
    }
    /*
     * build the grid map for physical <-> index space conversions
     */
    gm = gridmap_build(gridnodes_getnce1(gn), gridnodes_getnce2(gn), gridnodes_getx(gn), gridnodes_gety(gn));

    /*
     * convert bathymetry to index space if necessary 
     */
    if (indexspace) {
        point* newpbathy = malloc(nbathy * sizeof(point));
        int newnbathy = 0;
        int ii;

        for (ii = 0; ii < nbathy; ++ii) {
            point* p = &pbathy[ii];
            point* newp = &newpbathy[newnbathy];
            double ic, jc;

            if (gridmap_xy2fij(gm, p->x, p->y, &ic, &jc)) {
                newp->x = ic;
                newp->y = jc;
                newp->z = p->z;
                newnbathy++;
            }
        }

        free(pbathy);
        pbathy = newpbathy;
        nbathy = newnbathy;
    }

    /*
     * create interpolator 
     */
    if (rule == CSA) {          /* using libcsa */
        interpolator = csa_create();
        csa_addpoints(interpolator, nbathy, pbathy);
        csa_calculatespline(interpolator);
        interpolate_point = (void (*)(void*, point *)) csa_approximatepoint;
    } else if (rule == AVERAGE) {
        interpolator = ga_create(gm);
        ga_addpoints(interpolator, nbathy, pbathy);
        interpolate_point = (void (*)(void*, point *)) ga_getvalue;
        ppe = 1;
    } else {                    /* using libnn */
        /*
         * triangulate 
         */
        if (gu_verbose) {
            fprintf(stderr, "## triangulating...");
            fflush(stdout);
        }
        d = delaunay_build(nbathy, pbathy, 0, NULL, 0, NULL);
        if (gu_verbose) {
            fprintf(stderr, "done\n");
            fflush(stderr);
        }

        if (rule == NN_SIBSON || rule == NN_NONSIBSONIAN) {
            interpolator = nnpi_create(d);
            if (rule == NN_SIBSON)
                nn_rule = SIBSON;
            else
                nn_rule = NON_SIBSONIAN;
            interpolate_point = (void (*)(void*, point *)) nnpi_interpolate_point;
        } else if (rule == LINEAR) {
            interpolator = lpi_build(d);
            interpolate_point = (void (*)(void*, point *)) lpi_interpolate_point;
        }
    }

    /*
     * main cycle -- over grid cells 
     */
    {
        double** gx = gridnodes_getx(gn);
        int jmin, jmax, imin, imax;

        if (i < 0) {
            imin = 0;
            imax = gridnodes_getnce1(gn) - 1;
            jmin = 0;
            jmax = gridnodes_getnce2(gn) - 1;
        } else {
            if (gu_verbose)
                fprintf(stderr, "## calculating depth for cell (%d,%d)\n", i, j);
            imin = i;
            imax = i;
            jmin = j;
            jmax = j;
        }

        for (j = jmin; j <= jmax; ++j) {
            for (i = imin; i <= imax; ++i) {
                double sum = 0.0;
                int count = 0;
                int ii, jj;

                if ((mask != NULL && mask[j][i] == 0) || isnan(gx[j][i]) || isnan(gx[j + 1][i + 1]) || isnan(gx[j][i + 1]) || isnan(gx[j + 1][i])) {
                    printf("NaN\n");
                    continue;
                }

                for (ii = 0; ii < ppe; ++ii) {
                    for (jj = 0; jj < ppe; ++jj) {
                        double fi = (double) i + 0.5 / (double) ppe * (1.0 + 2.0 * (double) ii);
                        double fj = (double) j + 0.5 / (double) ppe * (1.0 + 2.0 * (double) jj);
                        point p;

                        if (!indexspace)
                            gridmap_fij2xy(gm, fi, fj, &p.x, &p.y);
                        else {
                            p.x = fi;
                            p.y = fj;
                        }

                        interpolate_point(interpolator, &p);

                        if (isnan(p.z))
                            continue;
                        else if (p.z < zmin)
                            p.z = zmin;
                        else if (p.z > zmax)
                            p.z = zmax;

                        sum += p.z;
                        count++;
                    }
                }

                if (count == 0)
                    printf("NaN\n");
                else
                    printf("%.2f\n", sum / (double) count);
                fflush(stdout);
            }
        }
    }

    /*
     * clean up, just because 
     */
    if (rule == CSA)
        csa_destroy(interpolator);
    else if (rule == AVERAGE)
        ga_destroy(interpolator);
    else {
        if (rule == NN_SIBSON || rule == NN_NONSIBSONIAN)
            nnpi_destroy(interpolator);
        else if (rule == LINEAR)
            lpi_destroy(interpolator);
        delaunay_destroy(d);
    }
    if (mask != NULL)
        gu_free2d(mask);
    gridmap_destroy(gm);
    gridnodes_destroy(gn);
    free(pbathy);

    return 0;
}