GeoConvHelper& GeoConvHelper::operator=(const GeoConvHelper& orig) { myProjString = orig.myProjString; myOffset = orig.myOffset; myProjectionMethod = orig.myProjectionMethod; myOrigBoundary = orig.myOrigBoundary; myConvBoundary = orig.myConvBoundary; myGeoScale = orig.myGeoScale; myUseInverseProjection = orig.myUseInverseProjection; #ifdef HAVE_PROJ if (myProjection != 0) { pj_free(myProjection); myProjection = 0; } if (myInverseProjection != 0) { pj_free(myInverseProjection); myInverseProjection = 0; } if (myGeoProjection != 0) { pj_free(myGeoProjection); myGeoProjection = 0; } if (orig.myProjection != 0) { myProjection = pj_init_plus(orig.myProjString.c_str()); } if (orig.myInverseProjection != 0) { myInverseProjection = pj_init_plus(pj_get_def(orig.myInverseProjection, 0)); } if (orig.myGeoProjection != 0) { myGeoProjection = pj_init_plus(pj_get_def(orig.myGeoProjection, 0)); } #endif return *this; }
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig) { RGeo_Proj4Data* self_data; projPJ pj; RGeo_Proj4Data* orig_data; char* str; // Clear out any existing value self_data = RGEO_PROJ4_DATA_PTR(self); pj = self_data->pj; if (pj) { pj_free(pj); self_data->pj = NULL; self_data->original_str = Qnil; } // Copy value from orig orig_data = RGEO_PROJ4_DATA_PTR(orig); if (!NIL_P(orig_data->original_str)) { self_data->pj = pj_init_plus(RSTRING_PTR(orig_data->original_str)); } else { str = pj_get_def(orig_data->pj, 0); self_data->pj = pj_init_plus(str); pj_dalloc(str); } self_data->original_str = orig_data->original_str; self_data->uses_radians = orig_data->uses_radians; return self; }
SEXP checkCRSArgs(SEXP args) { SEXP res; projPJ pj; PROTECT(res = NEW_LIST(2)); SET_VECTOR_ELT(res, 0, NEW_LOGICAL(1)); SET_VECTOR_ELT(res, 1, NEW_CHARACTER(1)); LOGICAL_POINTER(VECTOR_ELT(res, 0))[0] = FALSE; if (!(pj = pj_init_plus(CHAR(STRING_ELT(args, 0))))) { SET_STRING_ELT(VECTOR_ELT(res, 1), 0, COPY_TO_USER_STRING(pj_strerrno(*pj_get_errno_ref()))); UNPROTECT(1); return(res); } SET_STRING_ELT(VECTOR_ELT(res, 1), 0, COPY_TO_USER_STRING(pj_get_def(pj, 0))); LOGICAL_POINTER(VECTOR_ELT(res, 0))[0] = TRUE; UNPROTECT(1); return(res); }
std::string projection::expanded() const { #ifdef MAPNIK_USE_PROJ4 if (proj_) return mapnik::util::trim_copy(pj_get_def( proj_, 0 )); #endif return params_; }
/** Returns the PROJ.4 initialization string suitable for use with pj_init_plus() that would produce this coordinate system, but with the definition expanded as much as possible (for instance +init= and +datum= definitions). @param options Unused at this point */ std::string get_def(int options=0) const { char *pj_def = 0; pj_def = pj_get_def(pj, options); std::string ret = std::string(pj_def); pj_dalloc(pj_def); return ret; }
ProjCoordinateSystemPrivate::ProjCoordinateSystemPrivate(const ProjCoordinateSystemPrivate &other) : QSharedData(other), latLon(other.latLon) { char *str = pj_get_def(other.projection, 0); projection = pj_init_plus(str); Q_ASSERT_X(projection, "pj_init_plus", "invalid projection string"); free(str); }
/* Positive numbers refer the to the table above, negative numbers are assumed to refer to EPSG codes and it uses the proj4 to find those. */ reprojection::reprojection(int proj) : Proj(proj), pj_source(nullptr), pj_target(nullptr), pj_tile(nullptr), custom_projection(nullptr) { char buffer[32]; /* hard-code the source projection to be lat/lon, since OSM XML always * has coordinates in degrees. */ pj_source = pj_init_plus("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"); /* hard-code the tile projection to be spherical mercator always. * theoretically this could be made selectable but not all projections * lend themselves well to making tiles; non-spherical mercator tiles * are uncharted waters in OSM. */ pj_tile = pj_init_plus(Projection_Infos[PROJ_SPHERE_MERC].proj4text); /* now set the target projection - the only one which is really variable */ if (proj >= 0 && proj < PROJ_COUNT) { pj_target = pj_init_plus(Projection_Infos[proj].proj4text); } else if (proj < 0) { if (snprintf(buffer, sizeof(buffer), "+init=epsg:%d", -proj ) >= (int)sizeof(buffer)) { fprintf(stderr, "Buffer overflow computing proj4 initialisation string\n"); exit(1); } pj_target = pj_init_plus(buffer); if (!pj_target) { fprintf (stderr, "Couldn't read EPSG definition (do you have /usr/share/proj/epsg?)\n"); exit(1); } } if (!pj_source || !pj_target || !pj_tile) { fprintf(stderr, "Projection code failed to initialise\n"); exit(1); } if (proj >= 0) return; if (snprintf(buffer, sizeof(buffer), "EPSG:%d", -proj) >= (int)sizeof(buffer)) { fprintf(stderr, "Buffer overflow computing projection description\n"); exit(1); } custom_projection = new Projection_Info( strdup(buffer), pj_get_def(pj_target, 0), -proj, "-E"); }
QString Projection::getProjectionProj4() const { if (p->IsLatLong) return "+init=EPSG:4326"; else if (p->IsMercator) return "+init=EPSG:3857"; #ifndef _MOBILE else return QString(pj_get_def(theProj, 0)); #endif return QString(); }
Handle<Value> Projection::GetDefinition(Local<String> name, const AccessorInfo& info) { HandleScope scope; Projection *self = ObjectWrap::Unwrap<Projection>(info.Holder()); char *def; Handle<Value> def_obj; def = pj_get_def(self->pj, 0); def_obj = String::New(def); pj_dalloc(def); return scope.Close(def_obj); }
static VALUE method_proj4_canonical_str(VALUE self) { VALUE result = Qnil; projPJ pj = RGEO_PROJ4_DATA_PTR(self)->pj; if (pj) { char* str = pj_get_def(pj, 0); if (str) { result = rb_str_new2(str); pj_dalloc(str); } } return result; }
bool CMapRmap::setProjection(const QString& projection, const QString& datum) { QString projstr; if(projection.startsWith("0,UTM")) { QStringList vals = projection.split(","); int zone = vals[2].toInt(); bool isSouth = vals[3] != "N"; projstr += QString("+proj=utm +zone=%1 %2").arg(zone).arg(isSouth ? "+south" : ""); } if(projection.startsWith("1,")) { projstr += "+proj=longlat"; } else if(projection.startsWith("2,")) { projstr += "+proj=merc"; } else if(projection.startsWith("114,")) { projstr += "+proj=tmerc +lat_0=0 +lon_0=12 +k=1 +x_0=4500000 +y_0=0"; } else if(projection.startsWith("117,")) { projstr += "+proj=tmerc +lat_0=0 +lon_0=9 +k=1 +x_0=3500000 +y_0=0"; } if(datum == "WGS 84") { projstr += " +datum=WGS84 +units=m +no_defs"; } else if(datum == "Potsdam Rauenberg DHDN") { projstr += " +ellps=bessel +towgs84=606,23,413,0,0,0,0 +units=m +no_defs"; } pjsrc = pj_init_plus(projstr.toLatin1().data()); if(pjsrc == 0) { return false; } oSRS.importFromProj4(getProjection()); char * ptr = pj_get_def(pjsrc,0); qDebug() << "rmap:" << ptr; return true; }
/** * Serialise a proj-based projector a file. * * This function generates the canonical string representation of a proj *projection, * using the function pj_get_def; the length of the string followed by the *string itself * are then written to the file. * * @param p The proj-based projector to serialize. * @param output_file The file to serialize the projector to. */ void _proj_serialize_to_file(projector *p, FILE *output_file) { projPJ *projection = (projPJ *) p->internals; // Get the canonnical representation of the projection string char *projection_string = pj_get_def(projection, 0); // Calculate the length of the string, including the null terminator unsigned int projection_string_length = strlen(projection_string) + 1; // Write the projection string length and string to file fwrite(&projection_string_length, sizeof(unsigned int), 1, output_file); fwrite(projection_string, sizeof(char), projection_string_length, output_file); }
static projectionObj* msGetProjectNormalized( const projectionObj* p ) { int i; char* pszNewProj4Def; projectionObj* pnew; pnew = (projectionObj*)msSmallMalloc(sizeof(projectionObj)); msInitProjection(pnew); msCopyProjection(pnew, (projectionObj*)p); if(p->proj == NULL ) return pnew; /* Normalize definition so that msProjectDiffers() works better */ pszNewProj4Def = pj_get_def( p->proj, 0 ); msFreeCharArray(pnew->args, pnew->numargs); pnew->args = msStringSplit(pszNewProj4Def,'+', &pnew->numargs); for(i = 0; i < pnew->numargs; i++) { /* Remove trailing space */ if( strlen(pnew->args[i]) > 0 && pnew->args[i][strlen(pnew->args[i])-1] == ' ' ) pnew->args[i][strlen(pnew->args[i])-1] = '\0'; /* Remove spurious no_defs or init= */ if( strcmp(pnew->args[i], "no_defs") == 0 || strncmp(pnew->args[i], "init=", 5) == 0 ) { if( i < pnew->numargs - 1 ) { msFree(pnew->args[i]); memmove(pnew->args + i, pnew->args + i + 1, sizeof(char*) * (pnew->numargs - 1 -i )); } pnew->numargs --; i --; continue; } } /* Sort the strings so they can be compared */ qsort(pnew->args, pnew->numargs, sizeof(char*), msProjectSortString); /*{ fprintf(stderr, "'%s' =\n", pszNewProj4Def); for(i = 0; i < p->numargs; i++) fprintf(stderr, "'%s' ", p->args[i]); fprintf(stderr, "\n"); }*/ pj_dalloc(pszNewProj4Def); return pnew; }
/*! * \brief * retrieves projection parameters * * JNI informations: * Class: org_proj4_Projections * Method: getProjInfo * Signature: (Ljava/lang/String;)Ljava/lang/String; * * * \param env - parameter used by jni (see JNI specification) * \param parent - parameter used by jni (see JNI specification) * \param projdefinition - definition of the projection */ JNIEXPORT jstring JNICALL Java_org_proj4_Projections_getProjInfo (JNIEnv * env, jobject parent, jstring projdefinition) { PJ *pj; char * pjdesc; char info[arraysize]; char * proj_def = (char *) (*env)->GetStringUTFChars (env, projdefinition, 0); if (!(pj = pj_init_plus(proj_def))) exit(1); // put together all the info of the projection and free the pointer to pjdesc pjdesc = pj_get_def(pj, 0); strcpy(info,pjdesc); pj_dalloc(pjdesc); return (*env)->NewStringUTF(env,info); }
int point4d_transform(POINT4D *pt, projPJ srcpj, projPJ dstpj) { int* pj_errno_ref; POINT4D orig_pt; /* Make a copy of the input point so we can report the original should an error occur */ orig_pt.x = pt->x; orig_pt.y = pt->y; orig_pt.z = pt->z; if (pj_is_latlong(srcpj)) to_rad(pt) ; LWDEBUGF(4, "transforming POINT(%f %f) from '%s' to '%s'", orig_pt.x, orig_pt.y, pj_get_def(srcpj,0), pj_get_def(dstpj,0)); /* Perform the transform */ pj_transform(srcpj, dstpj, 1, 0, &(pt->x), &(pt->y), &(pt->z)); /* For NAD grid-shift errors, display an error message with an additional hint */ pj_errno_ref = pj_get_errno_ref(); if (*pj_errno_ref != 0) { if (*pj_errno_ref == -38) { lwnotice("PostGIS was unable to transform the point because either no grid shift files were found, or the point does not lie within the range for which the grid shift is defined. Refer to the ST_Transform() section of the PostGIS manual for details on how to configure PostGIS to alter this behaviour."); lwerror("transform: couldn't project point (%g %g %g): %s (%d)", orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref); return 0; } else { lwerror("transform: couldn't project point (%g %g %g): %s (%d)", orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref); return 0; } } if (pj_is_latlong(dstpj)) to_dec(pt); return 1; }
PJ_PROJ_INFO proj_pj_info(PJ *P) { /****************************************************************************** Basic info about a particular instance of a projection object. Returns PJ_PROJ_INFO struct. ******************************************************************************/ PJ_PROJ_INFO pjinfo; char *def; memset(&pjinfo, 0, sizeof(PJ_PROJ_INFO)); /* Expected accuracy of the transformation. Hardcoded for now, will be improved */ /* later. Most likely to be used when a transformation is set up with */ /* proj_create_crs_to_crs in a future version that leverages the EPSG database. */ pjinfo.accuracy = -1.0; if (0==P) return pjinfo; /* projection id */ if (pj_param(P->ctx, P->params, "tproj").i) pjinfo.id = pj_param(P->ctx, P->params, "sproj").s; /* projection description */ pjinfo.description = P->descr; /* projection definition */ if (P->def_full) def = P->def_full; else def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */ if (0==def) pjinfo.definition = empty; else pjinfo.definition = pj_shrink (def); /* Make pj_free clean this up eventually */ P->def_full = def; pjinfo.has_inverse = pj_has_inverse(P); return pjinfo; }
void print_proj4(int dontprettify) { struct pj_info pjinfo; char *proj4, *proj4mod, *i; const char *unfact; if (check_xy(FALSE)) return; if (pj_get_kv(&pjinfo, projinfo, projunits) == -1) G_fatal_error(_("Unable to convert projection information to PROJ.4 format")); proj4 = pj_get_def(pjinfo.pj, 0); pj_free(pjinfo.pj); /* GRASS-style PROJ.4 strings don't include a unit factor as this is * handled separately in GRASS - must include it here though */ unfact = G_find_key_value("meters", projunits); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); for (i = proj4mod; *i; i++) { /* Don't print the first space */ if (i == proj4mod && *i == ' ') continue; if (*i == ' ' && *(i+1) == '+' && !(dontprettify)) fputc('\n', stdout); else fputc(*i, stdout); } fputc('\n', stdout); G_free(proj4mod); return; }
/**Get the expanded definition of this projection as a string. call-seq: getDef -> String */ static VALUE proj_get_def(VALUE self){ _wrap_pj* wpj; Data_Get_Struct(self,_wrap_pj,wpj); return rb_str_new2(pj_get_def(wpj->pj, 0)); }
void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *y, double *z, TransformDirection direction ) const { if ( mShortCircuit || !mInitialisedFlag ) return; // Refuse to transform the points if the srs's are invalid if ( !mSourceCRS.isValid() ) { QgsMessageLog::logMessage( tr( "The source spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ) .arg( mSourceCRS.toProj4() ), tr( "CRS" ) ); return; } if ( !mDestCRS.isValid() ) { QgsMessageLog::logMessage( tr( "The destination spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ).arg( mDestCRS.toProj4() ), tr( "CRS" ) ); return; } #ifdef COORDINATE_TRANSFORM_VERBOSE double xorg = *x; double yorg = *y; QgsDebugMsg( QString( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) ); #endif // use proj4 to do the transform QString dir; // if the source/destination projection is lat/long, convert the points to radians // prior to transforming if (( pj_is_latlong( mDestinationProjection ) && ( direction == ReverseTransform ) ) || ( pj_is_latlong( mSourceProjection ) && ( direction == ForwardTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= DEG_TO_RAD; y[i] *= DEG_TO_RAD; } } int projResult; if ( direction == ReverseTransform ) { projResult = pj_transform( mDestinationProjection, mSourceProjection, numPoints, 0, x, y, z ); } else { Q_ASSERT( mSourceProjection ); Q_ASSERT( mDestinationProjection ); projResult = pj_transform( mSourceProjection, mDestinationProjection, numPoints, 0, x, y, z ); } if ( projResult != 0 ) { //something bad happened.... QString points; for ( int i = 0; i < numPoints; ++i ) { if ( direction == ForwardTransform ) { points += QString( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' ); } else { points += QString( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' ); } } dir = ( direction == ForwardTransform ) ? tr( "forward transform" ) : tr( "inverse transform" ); char *srcdef = pj_get_def( mSourceProjection, 0 ); char *dstdef = pj_get_def( mDestinationProjection, 0 ); QString msg = tr( "%1 of\n" "%2" "PROJ.4: %3 +to %4\n" "Error: %5" ) .arg( dir, points, srcdef, dstdef, QString::fromUtf8( pj_strerrno( projResult ) ) ); pj_dalloc( srcdef ); pj_dalloc( dstdef ); QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg ); emit invalidTransformInput(); QgsDebugMsg( "throwing exception" ); throw QgsCsException( msg ); } // if the result is lat/long, convert the results from radians back // to degrees if (( pj_is_latlong( mDestinationProjection ) && ( direction == ForwardTransform ) ) || ( pj_is_latlong( mSourceProjection ) && ( direction == ReverseTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= RAD_TO_DEG; y[i] *= RAD_TO_DEG; } } #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( QString( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" ) .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 ) .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) ); #endif }
void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *y, double *z, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) return; // Refuse to transform the points if the srs's are invalid if ( !d->mSourceCRS.isValid() ) { QgsMessageLog::logMessage( QObject::tr( "The source spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ) .arg( d->mSourceCRS.toProj4() ), QObject::tr( "CRS" ) ); return; } if ( !d->mDestCRS.isValid() ) { QgsMessageLog::logMessage( QObject::tr( "The destination spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ).arg( d->mDestCRS.toProj4() ), QObject::tr( "CRS" ) ); return; } #ifdef COORDINATE_TRANSFORM_VERBOSE double xorg = *x; double yorg = *y; QgsDebugMsg( QStringLiteral( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) ); #endif #ifdef QGISDEBUG if ( !mHasContext ) QgsDebugMsgLevel( QStringLiteral( "No QgsCoordinateTransformContext context set for transform" ), 4 ); #endif // use proj4 to do the transform // if the source/destination projection is lat/long, convert the points to radians // prior to transforming ProjData projData = d->threadLocalProjData(); #if PROJ_VERSION_MAJOR<6 bool sourceIsLatLong = false; bool destIsLatLong = false; projPJ sourceProj = projData.first; projPJ destProj = projData.second; sourceIsLatLong = pj_is_latlong( sourceProj ); destIsLatLong = pj_is_latlong( destProj ); if ( ( destIsLatLong && ( direction == ReverseTransform ) ) || ( sourceIsLatLong && ( direction == ForwardTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= DEG_TO_RAD; y[i] *= DEG_TO_RAD; } } #endif int projResult = 0; #if PROJ_VERSION_MAJOR>=6 const bool sourceAxisOrderSwapped = direction == ForwardTransform ? d->mSourceAxisOrderSwapped : d->mDestAxisOrderSwapped; proj_trans_generic( projData, direction == ForwardTransform ? PJ_FWD : PJ_INV, !sourceAxisOrderSwapped ? x : y, sizeof( double ), numPoints, !sourceAxisOrderSwapped ? y : x, sizeof( double ), numPoints, z, sizeof( double ), numPoints, nullptr, sizeof( double ), 0 ); projResult = proj_errno( projData ); // ewww - this logic is gross. We should drop support for PROJ 6.0 as quickly as possible and dump this code (in favour of built in methods used for >=6.1 builds) if ( projResult == 0 && ( d->mSourceAxisOrderSwapped != d->mDestAxisOrderSwapped ) ) { size_t size = sizeof( double ) * numPoints; void *tmp = malloc( size ); memcpy( tmp, x, size ); memcpy( x, y, size ); memcpy( y, tmp, size ); free( tmp ); } #else if ( direction == ReverseTransform ) { projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z ); } else { Q_ASSERT( sourceProj ); Q_ASSERT( destProj ); projResult = pj_transform( sourceProj, destProj, numPoints, 0, x, y, z ); } #endif if ( projResult != 0 ) { //something bad happened.... QString points; for ( int i = 0; i < numPoints; ++i ) { if ( direction == ForwardTransform ) { points += QStringLiteral( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' ); } else { #if PROJ_VERSION_MAJOR>=6 points += QStringLiteral( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' ); #else points += QStringLiteral( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' ); #endif } } QString dir = ( direction == ForwardTransform ) ? QObject::tr( "forward transform" ) : QObject::tr( "inverse transform" ); #if PROJ_VERSION_MAJOR>=6 QgsProjUtils::proj_pj_unique_ptr src( proj_get_source_crs( QgsProjContext::get(), projData ) ); QgsProjUtils::proj_pj_unique_ptr dest( proj_get_source_crs( QgsProjContext::get(), projData ) ); QString msg = QObject::tr( "%1 of\n" "%2" "PROJ: %3\n" "Error: %4" ) .arg( dir, points, proj_as_proj_string( QgsProjContext::get(), projData, PJ_PROJ_5, nullptr ), QString::fromUtf8( proj_errno_string( projResult ) ) ); #else char *srcdef = pj_get_def( sourceProj, 0 ); char *dstdef = pj_get_def( destProj, 0 ); QString msg = QObject::tr( "%1 of\n" "%2" "PROJ: %3 +to %4\n" "Error: %5" ) .arg( dir, points, srcdef, dstdef, QString::fromUtf8( pj_strerrno( projResult ) ) ); pj_dalloc( srcdef ); pj_dalloc( dstdef ); #endif QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg ); QgsDebugMsg( QStringLiteral( "throwing exception" ) ); throw QgsCsException( msg ); } #if PROJ_VERSION_MAJOR<6 // if the result is lat/long, convert the results from radians back // to degrees if ( ( destIsLatLong && ( direction == ForwardTransform ) ) || ( sourceIsLatLong && ( direction == ReverseTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= RAD_TO_DEG; y[i] *= RAD_TO_DEG; } } #endif #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( QStringLiteral( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" ) .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 ) .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) ); #endif }
void QgsCoordinateTransform::transformCoords( int numPoints, double *x, double *y, double *z, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) return; // Refuse to transform the points if the srs's are invalid if ( !d->mSourceCRS.isValid() ) { QgsMessageLog::logMessage( QObject::tr( "The source spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ) .arg( d->mSourceCRS.toProj4() ), QObject::tr( "CRS" ) ); return; } if ( !d->mDestCRS.isValid() ) { QgsMessageLog::logMessage( QObject::tr( "The destination spatial reference system (CRS) is not valid. " "The coordinates can not be reprojected. The CRS is: %1" ).arg( d->mDestCRS.toProj4() ), QObject::tr( "CRS" ) ); return; } #ifdef COORDINATE_TRANSFORM_VERBOSE double xorg = *x; double yorg = *y; QgsDebugMsg( QStringLiteral( "[[[[[[ Number of points to transform: %1 ]]]]]]" ).arg( numPoints ) ); #endif #ifdef QGISDEBUG if ( !mHasContext ) QgsDebugMsgLevel( QStringLiteral( "No QgsCoordinateTransformContext context set for transform" ), 4 ); #endif // use proj4 to do the transform // if the source/destination projection is lat/long, convert the points to radians // prior to transforming QPair<projPJ, projPJ> projData = d->threadLocalProjData(); projPJ sourceProj = projData.first; projPJ destProj = projData.second; if ( ( pj_is_latlong( destProj ) && ( direction == ReverseTransform ) ) || ( pj_is_latlong( sourceProj ) && ( direction == ForwardTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= DEG_TO_RAD; y[i] *= DEG_TO_RAD; } } int projResult; if ( direction == ReverseTransform ) { projResult = pj_transform( destProj, sourceProj, numPoints, 0, x, y, z ); } else { Q_ASSERT( sourceProj ); Q_ASSERT( destProj ); projResult = pj_transform( sourceProj, destProj, numPoints, 0, x, y, z ); } if ( projResult != 0 ) { //something bad happened.... QString points; for ( int i = 0; i < numPoints; ++i ) { if ( direction == ForwardTransform ) { points += QStringLiteral( "(%1, %2)\n" ).arg( x[i], 0, 'f' ).arg( y[i], 0, 'f' ); } else { points += QStringLiteral( "(%1, %2)\n" ).arg( x[i] * RAD_TO_DEG, 0, 'f' ).arg( y[i] * RAD_TO_DEG, 0, 'f' ); } } QString dir = ( direction == ForwardTransform ) ? QObject::tr( "forward transform" ) : QObject::tr( "inverse transform" ); char *srcdef = pj_get_def( sourceProj, 0 ); char *dstdef = pj_get_def( destProj, 0 ); QString msg = QObject::tr( "%1 of\n" "%2" "PROJ: %3 +to %4\n" "Error: %5" ) .arg( dir, points, srcdef, dstdef, QString::fromUtf8( pj_strerrno( projResult ) ) ); pj_dalloc( srcdef ); pj_dalloc( dstdef ); QgsDebugMsg( "Projection failed emitting invalid transform signal: " + msg ); QgsDebugMsg( QStringLiteral( "throwing exception" ) ); throw QgsCsException( msg ); } // if the result is lat/long, convert the results from radians back // to degrees if ( ( pj_is_latlong( destProj ) && ( direction == ForwardTransform ) ) || ( pj_is_latlong( sourceProj ) && ( direction == ReverseTransform ) ) ) { for ( int i = 0; i < numPoints; ++i ) { x[i] *= RAD_TO_DEG; y[i] *= RAD_TO_DEG; } } #ifdef COORDINATE_TRANSFORM_VERBOSE QgsDebugMsg( QStringLiteral( "[[[[[[ Projected %1, %2 to %3, %4 ]]]]]]" ) .arg( xorg, 0, 'g', 15 ).arg( yorg, 0, 'g', 15 ) .arg( *x, 0, 'g', 15 ).arg( *y, 0, 'g', 15 ) ); #endif }
SEXP transform(SEXP fromargs, SEXP toargs, SEXP npts, SEXP x, SEXP y) { /* interface to pj_transform() to be able to use longlat proj * and datum transformation in an SEXP format */ int i, n; double *xx, *yy, *zz; projPJ fromPJ, toPJ; SEXP res; if (!(fromPJ = pj_init_plus(CHAR(STRING_ELT(fromargs, 0))))) error(pj_strerrno(*pj_get_errno_ref())); if (!(toPJ = pj_init_plus(CHAR(STRING_ELT(toargs, 0))))) error(pj_strerrno(*pj_get_errno_ref())); n = INTEGER_POINTER(npts)[0]; xx = (double *) R_alloc((long) n, sizeof(double)); yy = (double *) R_alloc((long) n, sizeof(double)); zz = (double *) R_alloc((long) n, sizeof(double)); for (i=0; i < n; i++) { xx[i] = NUMERIC_POINTER(x)[i]; yy[i] = NUMERIC_POINTER(y)[i]; zz[i] = (double) 0; } if ( pj_is_latlong(fromPJ) ) { for (i=0; i < n; i++) { xx[i] *= DEG_TO_RAD; yy[i] *= DEG_TO_RAD; } } PROTECT(res = NEW_LIST(4)); SET_VECTOR_ELT(res, 0, NEW_NUMERIC(n)); SET_VECTOR_ELT(res, 1, NEW_NUMERIC(n)); SET_VECTOR_ELT(res, 2, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(res, 2), 0, COPY_TO_USER_STRING(pj_get_def(fromPJ, 0))); SET_VECTOR_ELT(res, 3, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(res, 3), 0, COPY_TO_USER_STRING(pj_get_def(toPJ, 0))); if( pj_transform( fromPJ, toPJ, (long) n, 0, xx, yy, zz ) != 0 ) { pj_free(fromPJ); pj_free(toPJ); Rprintf("error in pj_transform\n"); error(pj_strerrno(*pj_get_errno_ref())); } pj_free(fromPJ); pj_free(toPJ); if ( pj_is_latlong(toPJ) ) { for (i=0; i < n; i++) { xx[i] *= RAD_TO_DEG; yy[i] *= RAD_TO_DEG; } } for (i=0; i < n; i++) { if (xx[i] == HUGE_VAL || yy[i] == HUGE_VAL || ISNAN(xx[i]) || ISNAN(yy[i])) { Rprintf("transformed point not finite\n"); } NUMERIC_POINTER(VECTOR_ELT(res, 0))[i] = xx[i]; NUMERIC_POINTER(VECTOR_ELT(res, 1))[i] = yy[i]; } UNPROTECT(1); return(res); }
/** Copy constructor */ Proj(const Proj &h) { char *pj_def = pj_get_def(h.pj, 0); pj = pj_init_plus(pj_def); pj_dalloc(pj_def); }
OGRSpatialReferenceH GPJ_grass_to_osr(struct Key_Value * proj_info, struct Key_Value * proj_units) { struct pj_info pjinfo; char *proj4, *proj4mod, *wkt, *modwkt, *startmod, *lastpart; OGRSpatialReferenceH hSRS, hSRS2; OGRErr errcode; struct gpj_datum dstruct; struct gpj_ellps estruct; size_t len; const char *ellpskv, *unit, *unfact; char *ellps, *ellpslong, *datum, *params, *towgs84, *datumlongname, *start, *end; const char *sysname, *osrunit, *osrunfact; double a, es, rf; int haveparams = 0; if ((proj_info == NULL) || (proj_units == NULL)) return NULL; hSRS = OSRNewSpatialReference(NULL); if (pj_get_kv(&pjinfo, proj_info, proj_units) < 0) { G_warning(_("Unable parse GRASS PROJ_INFO file")); return NULL; } if ((proj4 = pj_get_def(pjinfo.pj, 0)) == NULL) { G_warning(_("Unable get PROJ.4-style parameter string")); return NULL; } pj_free(pjinfo.pj); unit = G_find_key_value("unit", proj_units); unfact = G_find_key_value("meters", proj_units); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) { G_warning(_("OGR can't parse PROJ.4-style parameter string: " "%s (OGR Error code was %d)"), proj4mod, errcode); return NULL; } G_free(proj4mod); if ((errcode = OSRExportToWkt(hSRS, &wkt)) != OGRERR_NONE) { G_warning(_("OGR can't get WKT-style parameter string " "(OGR Error code was %d)"), errcode); return NULL; } ellpskv = G_find_key_value("ellps", proj_info); GPJ__get_ellipsoid_params(proj_info, &a, &es, &rf); haveparams = GPJ__get_datum_params(proj_info, &datum, ¶ms); if(ellpskv != NULL) ellps = G_store(ellpskv); else ellps = NULL; if ((datum == NULL) || (GPJ_get_datum_by_name(datum, &dstruct) < 0)) { datumlongname = G_store("unknown"); if (ellps == NULL) ellps = G_store("unnamed"); } else { datumlongname = G_store(dstruct.longname); if (ellps == NULL) ellps = G_store(dstruct.ellps); GPJ_free_datum(&dstruct); } G_free(datum); if (GPJ_get_ellipsoid_by_name(ellps, &estruct) > 0) { ellpslong = G_store(estruct.longname); DatumNameMassage(&ellpslong); GPJ_free_ellps(&estruct); } else ellpslong = G_store(ellps); startmod = strstr(wkt, "GEOGCS"); lastpart = strstr(wkt, "PRIMEM"); len = strlen(wkt) - strlen(startmod); wkt[len] = '\0'; if (haveparams == 2) { /* Only put datum params into the WKT if they were specifically * specified in PROJ_INFO */ char *paramkey, *paramvalue; paramkey = strtok(params, "="); paramvalue = params + strlen(paramkey) + 1; if (G_strcasecmp(paramkey, "towgs84") == 0) G_asprintf(&towgs84, ",TOWGS84[%s]", paramvalue); else towgs84 = G_store(""); G_free(params); } else towgs84 = G_store(""); sysname = OSRGetAttrValue(hSRS, "PROJCS", 0); if (sysname == NULL) { /* Not a projected co-ordinate system */ start = G_store(""); end = G_store(""); } else { if ((strcmp(sysname, "unnamed") == 0) && (G_find_key_value("name", proj_info) != NULL)) G_asprintf(&start, "PROJCS[\"%s\",", G_find_key_value("name", proj_info)); else start = G_store(wkt); osrunit = OSRGetAttrValue(hSRS, "UNIT", 0); osrunfact = OSRGetAttrValue(hSRS, "UNIT", 1); if ((unfact == NULL) || (G_strcasecmp(osrunit, "unknown") != 0)) end = G_store(""); else { char *buff; double unfactf = atof(unfact); G_asprintf(&buff, ",UNIT[\"%s\",", osrunit); startmod = strstr(lastpart, buff); len = strlen(lastpart) - strlen(startmod); lastpart[len] = '\0'; G_free(buff); if (unit == NULL) unit = "unknown"; G_asprintf(&end, ",UNIT[\"%s\",%.16g]]", unit, unfactf); } } OSRDestroySpatialReference(hSRS); G_asprintf(&modwkt, "%sGEOGCS[\"%s\",DATUM[\"%s\",SPHEROID[\"%s\",%.16g,%.16g]%s],%s%s", start, ellps, datumlongname, ellpslong, a, rf, towgs84, lastpart, end); hSRS2 = OSRNewSpatialReference(modwkt); G_free(modwkt); CPLFree(wkt); G_free(start); G_free(ellps); G_free(datumlongname); G_free(ellpslong); G_free(towgs84); G_free(end); return hSRS2; }
ProjectionPointTransformer::ProjectionPointTransformer(projPJ from, projPJ to) { this->from = pj_init_plus(pj_get_def(from, 0)); this->to = pj_init_plus(pj_get_def(to, 0)); }
GeoConvHelper& GeoConvHelper::operator=(const GeoConvHelper& orig) { myProjString = orig.myProjString; myOffset = orig.myOffset; myProjectionMethod = orig.myProjectionMethod; myOrigBoundary = orig.myOrigBoundary; myConvBoundary = orig.myConvBoundary; myGeoScale = orig.myGeoScale; myCos = orig.myCos; mySin = orig.mySin; myUseInverseProjection = orig.myUseInverseProjection; myFlatten = orig.myFlatten; #ifdef PROJ_API_FILE if (myProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR proj_destroy(myProjection); #else pj_free(myProjection); #endif myProjection = nullptr; } if (myInverseProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR proj_destroy(myInverseProjection); #else pj_free(myInverseProjection); #endif myInverseProjection = nullptr; } if (myGeoProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR proj_destroy(myGeoProjection); #else pj_free(myGeoProjection); #endif myGeoProjection = nullptr; } if (orig.myProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR myProjection = proj_create(PJ_DEFAULT_CTX, orig.myProjString.c_str()); #else myProjection = pj_init_plus(orig.myProjString.c_str()); #endif } if (orig.myInverseProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR myInverseProjection = orig.myInverseProjection; #else myInverseProjection = pj_init_plus(pj_get_def(orig.myInverseProjection, 0)); #endif } if (orig.myGeoProjection != nullptr) { #ifdef PROJ_VERSION_MAJOR myGeoProjection = orig.myGeoProjection; #else myGeoProjection = pj_init_plus(pj_get_def(orig.myGeoProjection, 0)); #endif } #endif return *this; }