void* thread_main(void* unused) { projCtx p_proj_ctxt; projPJ p_WGS84_proj; projPJ p_OSGB36_proj; p_proj_ctxt=pj_ctx_alloc(); p_WGS84_proj=pj_init_plus_ctx(p_proj_ctxt,"+proj=longlat " "+ellps=WGS84 +datum=WGS84 +no_defs"); p_OSGB36_proj=pj_init_plus_ctx(p_proj_ctxt, "+proj=longlat +ellps=airy +datum=OSGB36 +nadgrids=OSTN02_NTv2.gsb " "+no_defs"); while(go_on) { double x, y; int proj_ret; x = -5.2*DEG_TO_RAD; y = 50*DEG_TO_RAD; proj_ret = pj_transform(p_WGS84_proj, p_OSGB36_proj, 1, 1, &x, &y, NULL ); x *= RAD_TO_DEG; y *= RAD_TO_DEG; /*printf("%.18f %.18f\n", x, y); */ assert(proj_ret == 0); assert(fabs(x - -5.198965360936369962) < 1e-15); assert(fabs(y - 49.999396034285531698) < 1e-15); } return NULL; }
static projPJ* custom_pj_init_plus_ctx(projCtx ctx, const char* def) { if( add_no_defs ) { char szBuffer[256]; strcpy(szBuffer, def); strcat(szBuffer, " +no_defs"); return pj_init_plus_ctx(ctx, szBuffer); } else return pj_init_plus_ctx(ctx, def); }
void projection::init_proj4() const { #ifdef MAPNIK_USE_PROJ4 if (!proj_) { #if PJ_VERSION >= 480 proj_ctx_ = pj_ctx_alloc(); proj_ = pj_init_plus_ctx(proj_ctx_, params_.c_str()); if (!proj_) { if (proj_ctx_) { pj_ctx_free(proj_ctx_); proj_ctx_ = 0; } throw proj_init_error(params_); } #else #if defined(MAPNIK_THREADSAFE) mapnik::scoped_lock lock(mutex_); #endif proj_ = pj_init_plus(params_.c_str()); if (!proj_) throw proj_init_error(params_); #endif is_geographic_ = pj_is_latlong(proj_) ? true : false; } #endif }
QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData() { mProjLock.lockForRead(); #ifdef USE_THREAD_LOCAL QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) ); #else projCtx pContext = nullptr; if ( mProjContext.hasLocalData() ) { pContext = mProjContext.localData()->get(); } else { mProjContext.setLocalData( new QgsProjContextStore() ); pContext = mProjContext.localData()->get(); } QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( pContext ) ); #endif if ( it != mProjProjections.constEnd() ) { QPair<projPJ, projPJ> res = it.value(); mProjLock.unlock(); return res; } // proj projections don't exist yet, so we need to create mProjLock.unlock(); mProjLock.lockForWrite(); #ifdef USE_THREAD_LOCAL QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ), pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) ); mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res ); #else QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( pContext, mSourceProjString.toUtf8() ), pj_init_plus_ctx( pContext, mDestProjString.toUtf8() ) ); mProjProjections.insert( reinterpret_cast< uintptr_t>( pContext ), res ); #endif mProjLock.unlock(); return res; }
QPair<projPJ, projPJ> QgsCoordinateTransformPrivate::threadLocalProjData() { mProjLock.lockForRead(); QMap < uintptr_t, QPair< projPJ, projPJ > >::const_iterator it = mProjProjections.constFind( reinterpret_cast< uintptr_t>( mProjContext.get() ) ); if ( it != mProjProjections.constEnd() ) { QPair<projPJ, projPJ> res = it.value(); mProjLock.unlock(); return res; } // proj projections don't exist yet, so we need to create mProjLock.unlock(); mProjLock.lockForWrite(); QPair<projPJ, projPJ> res = qMakePair( pj_init_plus_ctx( mProjContext.get(), mSourceProjString.toUtf8() ), pj_init_plus_ctx( mProjContext.get(), mDestProjString.toUtf8() ) ); mProjProjections.insert( reinterpret_cast< uintptr_t>( mProjContext.get() ), res ); mProjLock.unlock(); return res; }
PJ *pj_latlong_from_proj( PJ *pj_in ) { char defn[512]; int got_datum = FALSE; pj_errno = 0; strcpy( defn, "+proj=latlong" ); if( pj_param(pj_in->ctx, pj_in->params, "tdatum").i ) { got_datum = TRUE; sprintf( defn+strlen(defn), " +datum=%s", pj_param(pj_in->ctx, pj_in->params,"sdatum").s ); } else if( pj_param(pj_in->ctx, pj_in->params, "tellps").i ) { sprintf( defn+strlen(defn), " +ellps=%s", pj_param(pj_in->ctx, pj_in->params,"sellps").s ); } else if( pj_param(pj_in->ctx,pj_in->params, "ta").i ) { sprintf( defn+strlen(defn), " +a=%s", pj_param(pj_in->ctx,pj_in->params,"sa").s ); if( pj_param(pj_in->ctx,pj_in->params, "tb").i ) sprintf( defn+strlen(defn), " +b=%s", pj_param(pj_in->ctx,pj_in->params,"sb").s ); else if( pj_param(pj_in->ctx,pj_in->params, "tes").i ) sprintf( defn+strlen(defn), " +es=%s", pj_param(pj_in->ctx,pj_in->params,"ses").s ); else if( pj_param(pj_in->ctx,pj_in->params, "tf").i ) sprintf( defn+strlen(defn), " +f=%s", pj_param(pj_in->ctx,pj_in->params,"sf").s ); else sprintf( defn+strlen(defn), " +es=%.16g", pj_in->es ); } else { pj_ctx_set_errno( pj_in->ctx, -13 ); return NULL; } if( !got_datum ) { if( pj_param(pj_in->ctx,pj_in->params, "ttowgs84").i ) sprintf( defn+strlen(defn), " +towgs84=%s", pj_param(pj_in->ctx,pj_in->params,"stowgs84").s ); if( pj_param(pj_in->ctx,pj_in->params, "tnadgrids").i ) sprintf( defn+strlen(defn), " +nadgrids=%s", pj_param(pj_in->ctx,pj_in->params,"snadgrids").s ); } /* copy over some other information related to ellipsoid */ if( pj_param(pj_in->ctx,pj_in->params, "tR").i ) sprintf( defn+strlen(defn), " +R=%s", pj_param(pj_in->ctx,pj_in->params,"sR").s ); if( pj_param(pj_in->ctx,pj_in->params, "tR_A").i ) sprintf( defn+strlen(defn), " +R_A" ); if( pj_param(pj_in->ctx,pj_in->params, "tR_V").i ) sprintf( defn+strlen(defn), " +R_V" ); if( pj_param(pj_in->ctx,pj_in->params, "tR_a").i ) sprintf( defn+strlen(defn), " +R_a" ); if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_a").i ) sprintf( defn+strlen(defn), " +R_lat_a=%s", pj_param(pj_in->ctx,pj_in->params,"sR_lat_a").s ); if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_g").i ) sprintf( defn+strlen(defn), " +R_lat_g=%s", pj_param(pj_in->ctx,pj_in->params,"sR_lat_g").s ); /* copy over prime meridian */ if( pj_param(pj_in->ctx,pj_in->params, "tpm").i ) sprintf( defn+strlen(defn), " +pm=%s", pj_param(pj_in->ctx,pj_in->params,"spm").s ); return pj_init_plus_ctx( pj_in->ctx, defn ); }
static gaiaGeomCollPtr gaiaTransformCommon (projCtx handle, gaiaGeomCollPtr org, char *proj_from, char *proj_to) { /* creates a new GEOMETRY reprojecting coordinates from the original one */ int ib; int cnt; int i; double *xx; double *yy; double *zz; double *mm = NULL; double x; double y; double z = 0.0; double m = 0.0; int error = 0; int from_angle; int to_angle; gaiaPointPtr pt; gaiaLinestringPtr ln; gaiaLinestringPtr dst_ln; gaiaPolygonPtr pg; gaiaPolygonPtr dst_pg; gaiaRingPtr rng; gaiaRingPtr dst_rng; projPJ from_cs; projPJ to_cs; gaiaGeomCollPtr dst; if (handle != NULL) { from_cs = pj_init_plus_ctx (handle, proj_from); to_cs = pj_init_plus_ctx (handle, proj_to); } else { from_cs = pj_init_plus (proj_from); to_cs = pj_init_plus (proj_to); } if (!from_cs) { if (to_cs) pj_free (to_cs); return NULL; } if (!to_cs) { pj_free (from_cs); return NULL; } if (org->DimensionModel == GAIA_XY_Z) dst = gaiaAllocGeomCollXYZ (); else if (org->DimensionModel == GAIA_XY_M) dst = gaiaAllocGeomCollXYM (); else if (org->DimensionModel == GAIA_XY_Z_M) dst = gaiaAllocGeomCollXYZM (); else dst = gaiaAllocGeomColl (); /* setting up projection parameters */ from_angle = gaiaIsLongLat (proj_from); to_angle = gaiaIsLongLat (proj_to); cnt = 0; pt = org->FirstPoint; while (pt) { /* counting POINTs */ cnt++; pt = pt->Next; } if (cnt) { /* reprojecting POINTs */ xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); i = 0; pt = org->FirstPoint; while (pt) { /* inserting points to be converted in temporary arrays */ if (from_angle) { xx[i] = gaiaDegsToRads (pt->X); yy[i] = gaiaDegsToRads (pt->Y); } else { xx[i] = pt->X; yy[i] = pt->Y; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) zz[i] = pt->Z; else zz[i] = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) mm[i] = pt->M; i++; pt = pt->Next; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POINTs in the new GEOMETRY */ for (i = 0; i < cnt; i++) { if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (org->DimensionModel == GAIA_XY_Z || org->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst->DimensionModel == GAIA_XY_Z) gaiaAddPointToGeomCollXYZ (dst, x, y, z); else if (dst->DimensionModel == GAIA_XY_M) gaiaAddPointToGeomCollXYM (dst, x, y, m); else if (dst->DimensionModel == GAIA_XY_Z_M) gaiaAddPointToGeomCollXYZM (dst, x, y, z, m); else gaiaAddPointToGeomColl (dst, x, y); } } else error = 1; free (xx); free (yy); free (zz); if (org->DimensionModel == GAIA_XY_M || org->DimensionModel == GAIA_XY_Z_M) free (mm); } if (error) goto stop; ln = org->FirstLinestring; while (ln) { /* reprojecting LINESTRINGs */ cnt = ln->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays */ if (ln->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (ln->Coords, i, &x, &y, &z); } else if (ln->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (ln->Coords, i, &x, &y, &m); } else if (ln->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (ln->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (ln->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected LINESTRING in the new GEOMETRY */ dst_ln = gaiaAddLinestringToGeomColl (dst, cnt); for (i = 0; i < cnt; i++) { /* setting LINESTRING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (ln->DimensionModel == GAIA_XY_Z || ln->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_ln->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_ln->Coords, i, x, y, z); } else if (dst_ln->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_ln->Coords, i, x, y, m); } else if (dst_ln->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_ln->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_ln->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (ln->DimensionModel == GAIA_XY_M || ln->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; ln = ln->Next; } pg = org->FirstPolygon; while (pg) { /* reprojecting POLYGONs */ rng = pg->Exterior; cnt = rng->Points; dst_pg = gaiaAddPolygonToGeomColl (dst, cnt, pg->NumInteriors); xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [EXTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = dst_pg->Exterior; for (i = 0; i < cnt; i++) { /* setting EXTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; for (ib = 0; ib < pg->NumInteriors; ib++) { /* processing INTERIOR RINGS */ rng = pg->Interiors + ib; cnt = rng->Points; xx = malloc (sizeof (double) * cnt); yy = malloc (sizeof (double) * cnt); zz = malloc (sizeof (double) * cnt); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm = malloc (sizeof (double) * cnt); for (i = 0; i < cnt; i++) { /* inserting points to be converted in temporary arrays [INTERIOR RING] */ if (rng->DimensionModel == GAIA_XY_Z) { gaiaGetPointXYZ (rng->Coords, i, &x, &y, &z); } else if (rng->DimensionModel == GAIA_XY_M) { gaiaGetPointXYM (rng->Coords, i, &x, &y, &m); } else if (rng->DimensionModel == GAIA_XY_Z_M) { gaiaGetPointXYZM (rng->Coords, i, &x, &y, &z, &m); } else { gaiaGetPoint (rng->Coords, i, &x, &y); } if (from_angle) { xx[i] = gaiaDegsToRads (x); yy[i] = gaiaDegsToRads (y); } else { xx[i] = x; yy[i] = y; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) zz[i] = z; else zz[i] = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) mm[i] = m; } /* applying reprojection */ if (pj_transform (from_cs, to_cs, cnt, 0, xx, yy, zz) == 0) { /* inserting the reprojected POLYGON in the new GEOMETRY */ dst_rng = gaiaAddInteriorRing (dst_pg, ib, cnt); for (i = 0; i < cnt; i++) { /* setting INTERIOR RING points */ if (to_angle) { x = gaiaRadsToDegs (xx[i]); y = gaiaRadsToDegs (yy[i]); } else { x = xx[i]; y = yy[i]; } if (rng->DimensionModel == GAIA_XY_Z || rng->DimensionModel == GAIA_XY_Z_M) z = zz[i]; else z = 0.0; if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) m = mm[i]; else m = 0.0; if (dst_rng->DimensionModel == GAIA_XY_Z) { gaiaSetPointXYZ (dst_rng->Coords, i, x, y, z); } else if (dst_rng->DimensionModel == GAIA_XY_M) { gaiaSetPointXYM (dst_rng->Coords, i, x, y, m); } else if (dst_rng->DimensionModel == GAIA_XY_Z_M) { gaiaSetPointXYZM (dst_rng->Coords, i, x, y, z, m); } else { gaiaSetPoint (dst_rng->Coords, i, x, y); } } } else error = 1; free (xx); free (yy); free (zz); if (rng->DimensionModel == GAIA_XY_M || rng->DimensionModel == GAIA_XY_Z_M) free (mm); if (error) goto stop; } pg = pg->Next; } /* destroying the PROJ4 params */ stop: pj_free (from_cs); pj_free (to_cs); if (error) { /* some error occurred */ gaiaPointPtr pP; gaiaPointPtr pPn; gaiaLinestringPtr pL; gaiaLinestringPtr pLn; gaiaPolygonPtr pA; gaiaPolygonPtr pAn; pP = dst->FirstPoint; while (pP != NULL) { pPn = pP->Next; gaiaFreePoint (pP); pP = pPn; } pL = dst->FirstLinestring; while (pL != NULL) { pLn = pL->Next; gaiaFreeLinestring (pL); pL = pLn; } pA = dst->FirstPolygon; while (pA != NULL) { pAn = pA->Next; gaiaFreePolygon (pA); pA = pAn; } dst->FirstPoint = NULL; dst->LastPoint = NULL; dst->FirstLinestring = NULL; dst->LastLinestring = NULL; dst->FirstPolygon = NULL; dst->LastPolygon = NULL; } if (dst) { gaiaMbrGeometry (dst); dst->DeclaredType = org->DeclaredType; } return dst; }
PJ * pj_init_plus( const char *definition ) { return pj_init_plus_ctx( pj_get_default_ctx(), definition ); }
void QgsCustomProjectionDialog::pbnCalculate_clicked() { // We must check the prj def is valid! projCtx pContext = pj_ctx_alloc(); projPJ proj = pj_init_plus_ctx( pContext, teParameters->toPlainText().toLocal8Bit().data() ); QgsDebugMsg( QString( "Proj: %1" ).arg( teParameters->toPlainText() ) ); if ( !proj ) { QMessageBox::information( this, tr( "QGIS Custom Projection" ), tr( "This proj4 projection definition is not valid." ) ); projectedX->clear(); projectedY->clear(); pj_free( proj ); pj_ctx_free( pContext ); return; } // Get the WGS84 coordinates bool okN, okE; double northing = northWGS84->text().toDouble( &okN ) * DEG_TO_RAD; double easting = eastWGS84->text().toDouble( &okE ) * DEG_TO_RAD; if ( !okN || !okE ) { QMessageBox::information( this, tr( "QGIS Custom Projection" ), tr( "Northing and Easthing must be in decimal form." ) ); projectedX->clear(); projectedY->clear(); pj_free( proj ); pj_ctx_free( pContext ); return; } projPJ wgs84Proj = pj_init_plus_ctx( pContext, GEOPROJ4.toLocal8Bit().data() ); //defined in qgis.h if ( !wgs84Proj ) { QMessageBox::information( this, tr( "QGIS Custom Projection" ), tr( "Internal Error (source projection invalid?)" ) ); projectedX->clear(); projectedY->clear(); pj_free( wgs84Proj ); pj_ctx_free( pContext ); return; } double z = 0.0; int projResult = pj_transform( wgs84Proj, proj, 1, 0, &easting, &northing, &z ); if ( projResult != 0 ) { projectedX->setText( tr( "Error" ) ); projectedY->setText( tr( "Error" ) ); QgsDebugMsg( pj_strerrno( projResult ) ); } else { QString tmp; int precision = 4; if ( pj_is_latlong( proj ) ) { northing *= RAD_TO_DEG; easting *= RAD_TO_DEG; precision = 7; } tmp = QLocale::system().toString( northing, 'f', precision ); projectedX->setText( tmp ); tmp = QLocale::system().toString( easting, 'f', precision ); projectedY->setText( tmp ); } pj_free( proj ); pj_free( wgs84Proj ); pj_ctx_free( pContext ); }
void run(const TProjection& p, const ForwardIterableInputRange& x, const ForwardIterableInputRange& y, ForwardIterableOutputRange& out_x, ForwardIterableOutputRange& out_y) const { size_t sx = boost::size(x); // data sanity assert(sx == boost::size(y)); assert(boost::size(y) == boost::size(out_x)); assert(boost::size(out_x) == boost::size(out_y)); std::string from = projection_to_string(p.from); std::string to = projection_to_string(p.to); auto compute = [&p, &from, &to](double *x, double *y, double *z, size_t stride, size_t point_count) { projCtx ctx = pj_ctx_alloc(); projPJ pj_in = pj_init_plus_ctx(ctx, from.c_str()), pj_out = pj_init_plus_ctx(ctx, to.c_str()); assert(pj_in != NULL); assert(pj_out != NULL); detail::pre_process(p.from, x, y, point_count); // fasten your seatbelts pj_transform(pj_in, pj_out, static_cast<long>(point_count), static_cast<int>(stride), x, y, NULL); pj_free(pj_in); pj_free(pj_out); pj_ctx_free(ctx); detail::post_process(p.to, x, y, point_count); }; typedef typename boost::range_iterator<ForwardIterableOutputRange>::type iterator; typedef typename boost::range_const_iterator<ForwardIterableInputRange>::type const_iterator; // projcl does in-place transforms, so move all input values to output const_iterator bx = boost::begin(x), by = boost::begin(y); iterator ox = boost::begin(out_x), oy = boost::begin(out_y); std::copy(bx, boost::end(x), ox); std::copy(by, boost::end(y), oy); utility::scheduler<MaxConcurrency> c; unsigned max_threads = c.concurrency(); size_t per_batch = sx / max_threads; size_t offset = 0; for (unsigned i = 0 ; i < max_threads ; i ++) { double *x = &(*(ox + offset)); double *y = &(*(oy + offset)); double *z = NULL; c.queue(compute, x, y, z, 1, per_batch); offset += per_batch; } c.wait(); }
static void TestThread() { int i, test_count = sizeof(test_list) / sizeof(TestItem); int repeat_count = num_iterations; int i_iter; /* -------------------------------------------------------------------- */ /* Initialize coordinate system definitions. */ /* -------------------------------------------------------------------- */ projPJ *src_pj_list, *dst_pj_list; projCtx ctx = pj_ctx_alloc(); // projCtx ctx = pj_get_default_ctx(); src_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ)); dst_pj_list = (projPJ *) calloc(test_count,sizeof(projPJ)); #if reinit_every_iteration == 0 for( i = 0; i < test_count; i++ ) { TestItem *test = test_list + i; src_pj_list[i] = pj_init_plus_ctx( ctx, test->src_def ); dst_pj_list[i] = pj_init_plus_ctx( ctx, test->dst_def ); } #endif /* -------------------------------------------------------------------- */ /* Perform tests - over and over. */ /* -------------------------------------------------------------------- */ for( i_iter = 0; i_iter < repeat_count; i_iter++ ) { for( i = 0; i < test_count; i++ ) { TestItem *test = test_list + i; double x, y, z; int error; int skipTest = test->skip; x = test->src_x; y = test->src_y; z = test->src_z; #if reinit_every_iteration == 1 src_pj_list[i] = pj_init_plus_ctx( ctx, test->src_def ); dst_pj_list[i] = pj_init_plus_ctx( ctx, test->dst_def ); { int skipTest = (src_pj_list[i] == NULL || dst_pj_list[i] == NULL); if ( skipTest != test->skip ) fprintf( stderr, "Threaded projection initialization does not match unthreaded initialization\n" ); if (skipTest) { pj_free( src_pj_list[i] ); pj_free( dst_pj_list[i] ); continue; } } #endif if ( test->skip ) continue; error = pj_transform( src_pj_list[i], dst_pj_list[i], 1, 0, &x, &y, &z ); if( error != test->dst_error ) { fprintf( stderr, "Got error %d, expected %d\n", error, test->dst_error ); } if( x != test->dst_x || y != test->dst_y || z != test->dst_z ) { fprintf( stderr, "Got %.15g,%.15g,%.15g\n" "Expected %.15g,%.15g,%.15g\n", x, y, z, test->dst_x, test->dst_y, test->dst_z ); } #if reinit_every_iteration == 1 pj_free( src_pj_list[i] ); pj_free( dst_pj_list[i] ); #endif } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ #if reinit_every_iteration == 0 for( i = 0; i < test_count; i++ ) { pj_free( src_pj_list[i] ); pj_free( dst_pj_list[i] ); } #endif free( src_pj_list ); free( dst_pj_list ); pj_ctx_free( ctx ); printf( "%d iterations of the %d tests complete in thread X\n", repeat_count, test_count ); active_thread_count--; }