public static Transform GetUserSRSToModelTransform(OSGeo.OSR.SpatialReference userSRS) { ///TODO: Check what units the userSRS is in and coordinate with the scaling function. Currently only accounts for a userSRS in meters. ///TODO: translate or scale GCS (decimal degrees) to something like a Projectected Coordinate System. Need to go dd to xy ///transform rhino EAP from rhinoSRS to userSRS double eapLat = EarthAnchorPoint.EarthBasepointLatitude; double eapLon = EarthAnchorPoint.EarthBasepointLongitude; double eapElev = EarthAnchorPoint.EarthBasepointElevation; Plane eapPlane = EarthAnchorPoint.GetEarthAnchorPlane(out Vector3d eapNorth); OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(rhinoSRS, userSRS); OSGeo.OGR.Geometry userAnchorPointDD = Heron.Convert.Point3dToOgrPoint(new Point3d(eapLon, eapLat, eapElev)); Transform t = new Transform(1.0); userAnchorPointDD.Transform(coordTransform); Point3d userAnchorPointPT = Heron.Convert.OgrPointToPoint3d(userAnchorPointDD, t); ///setup userAnchorPoint plane for move and rotation double eapLatNorth = EarthAnchorPoint.EarthBasepointLatitude + 0.5; double eapLonEast = EarthAnchorPoint.EarthBasepointLongitude + 0.5; OSGeo.OGR.Geometry userAnchorPointDDNorth = Heron.Convert.Point3dToOgrPoint(new Point3d(eapLon, eapLatNorth, eapElev)); OSGeo.OGR.Geometry userAnchorPointDDEast = Heron.Convert.Point3dToOgrPoint(new Point3d(eapLonEast, eapLat, eapElev)); userAnchorPointDDNorth.Transform(coordTransform); userAnchorPointDDEast.Transform(coordTransform); Point3d userAnchorPointPTNorth = Heron.Convert.OgrPointToPoint3d(userAnchorPointDDNorth, t); Point3d userAnchorPointPTEast = Heron.Convert.OgrPointToPoint3d(userAnchorPointDDEast, t); Vector3d userAnchorNorthVec = userAnchorPointPTNorth - userAnchorPointPT; Vector3d userAnchorEastVec = userAnchorPointPTEast - userAnchorPointPT; Plane userEapPlane = new Plane(userAnchorPointPT, userAnchorEastVec, userAnchorNorthVec); ///shift (move and rotate) from userSRS EAP to 0,0 based on SRS north direction Transform scale = Transform.Scale(new Point3d(0.0, 0.0, 0.0), (1 / Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters))); if (userSRS.GetLinearUnitsName().ToUpper().Contains("FEET") || userSRS.GetLinearUnitsName().ToUpper().Contains("FOOT")) { scale = Transform.Scale(new Point3d(0.0, 0.0, 0.0), (1 / Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Feet))); } ///if SRS is geographic (ie WGS84) use Rhino's internal projection ///this is still buggy as it doesn't work with other geographic systems like NAD27 if ((userSRS.IsProjected() == 0) && (userSRS.IsLocal() == 0)) { userEapPlane.Transform(WGSToXYZTransform()); scale = WGSToXYZTransform(); } Transform shift = Transform.ChangeBasis(eapPlane, userEapPlane); Transform shiftScale = Transform.Multiply(scale, shift); return(shiftScale); }