/** * @param SimpleXMLElement $xml * @return TrackSegment * @throws InvalidGPXException */ public static function fromXML(SimpleXMLElement $xml) { $trackSegment = new TrackSegment(); if (!empty($xml->trkpt)) { $trackPoints = []; foreach ($xml->trkpt as $trackPoint) { array_push($trackPoints, Waypoint::fromXML($trackPoint)); } $trackSegment->setTrackPoints($trackPoints); } if (!empty($xml->extensions)) { $trackSegment->setExtensions(Extensions::fromXML($xml->extensions[0])); } return $trackSegment; }
/** * @param SimpleXMLElement $xml * @return Waypoint * @throws InvalidGPXException */ public static function fromXML(SimpleXMLElement $xml) { $attributes = $xml->attributes(); if (!($latitude = $attributes['lat'])) { throw new InvalidGPXException("No latitude specified on waypoint node."); } if (!($longitude = $attributes['lon'])) { throw new InvalidGPXException("No longitude specified on waypoint node."); } $waypoint = new Waypoint((double) $latitude, (double) $longitude); if (!empty($xml->ele)) { $waypoint->setElevation((double) $xml->ele[0]); } if (!empty($xml->time)) { $waypoint->setTime(strtotime((string) $xml->time[0])); } if (!empty($xml->magvar)) { $waypoint->setMagvar((double) $xml->magvar[0]); } if (!empty($xml->geoidheight)) { $waypoint->setGeoidheight((double) $xml->geoidheight[0]); } if (!empty($xml->name)) { $waypoint->setName((string) $xml->name[0]); } if (!empty($xml->cmt)) { $waypoint->setComment((string) $xml->cmt[0]); } if (!empty($xml->desc)) { $waypoint->setDescription((string) $xml->desc[0]); } if (!empty($xml->src)) { $waypoint->setSource((string) $xml->src[0]); } if (!empty($xml->link)) { $links = []; foreach ($xml->link as $link) { array_push($links, Link::fromXML($link)); } $waypoint->setLinks($links); } if (!empty($xml->sym)) { $waypoint->setSymbol((string) $xml->sym[0]); } if (!empty($xml->type)) { $waypoint->setType((string) $xml->type[0]); } if (!empty($xml->fix)) { $waypoint->setFix((string) $xml->fix[0]); } if (!empty($xml->sat)) { $waypoint->setFix((int) $xml->sat[0]); } if (!empty($xml->hdop)) { $waypoint->setHdop((double) $xml->hdop[0]); } if (!empty($xml->vdop)) { $waypoint->setVdop((double) $xml->vdop[0]); } if (!empty($xml->pdop)) { $waypoint->setPdop((double) $xml->pdop[0]); } if (!empty($xml->ageofdgpsdata)) { $waypoint->setAgeofdgpsdata((double) $xml->ageofdgpsdata[0]); } if (!empty($xml->dgpsid)) { $waypoint->setDgpsid((int) $xml->dgpsid[0]); } if (!empty($xml->extensions)) { $waypoint->setExtensions(Extensions::fromXML($xml->extensions[0])); } return $waypoint; }
/** * @param SimpleXMLElement $xml * @return Route * @throws InvalidGPXException */ public static function fromXML(SimpleXMLElement $xml) { $route = new Route(); if (!empty($xml->name)) { $route->setName((string) $xml->name[0]); } if (!empty($xml->cmt)) { $route->setComment((string) $xml->cmt[0]); } if (!empty($xml->desc)) { $route->setDescription((string) $xml->desc[0]); } if (!empty($xml->src)) { $route->setSource((string) $xml->src[0]); } if (!empty($xml->link)) { $links = []; foreach ($xml->link as $link) { array_push($links, Link::fromXML($link)); } $route->setLinks($links); } if (!empty($xml->number)) { $route->setNumber((int) $xml->number[0]); } if (!empty($xml->type)) { $route->setType((string) $xml->type[0]); } if (!empty($xml->extensions)) { $route->setExtensions(Extensions::fromXML($xml->extensions[0])); } if (!empty($xml->rtept)) { $routePoints = []; foreach ($xml->rtept as $routePoint) { array_push($routePoints, Waypoint::fromXML($routePoint)); } $route->setRoutePoints($routePoints); } return $route; }
/** * @param SimpleXMLElement $xml * @return GPX * @throws InvalidGPXException */ public static function fromXML(SimpleXMLElement $xml) { if ($xml->getName() != 'gpx') { throw new InvalidGPXException("Root node should be 'gpx'"); } $attributes = $xml->attributes(); $version = $attributes['version']; if ($version != 1.1) { throw new InvalidGPXException("Invalid GPX version. This library only supports GPX 1.1"); } if (!($creator = $attributes['creator'])) { throw new InvalidGPXException("No creator specified on GPX node."); } $gpx = new GPX((double) $version, (string) $creator); if (!empty($xml->metadata)) { $gpx->setMetadata(Metadata::fromXML($xml->metadata[0])); } if (!empty($xml->wpt)) { $waypoints = []; foreach ($xml->wpt as $waypoint) { array_push($waypoints, Waypoint::fromXML($waypoint)); } $gpx->setWaypoints($waypoints); } if (!empty($xml->rte)) { $routes = []; foreach ($xml->rte as $route) { array_push($routes, Route::fromXML($route)); } $gpx->setRoutes($routes); } if (!empty($xml->trk)) { $tracks = []; foreach ($xml->trk as $track) { array_push($tracks, Track::fromXML($track)); } $gpx->setTracks($tracks); } if (!empty($xml->extensions)) { $gpx->setExtensions(Extensions::fromXML($xml->extensions[0])); } return $gpx; }
/** * Read a single section (route or track) of a GPX file and add it to the total route * The sections are merged into one, with a straight line between the end of one and the start of the next. * * @param DOMElement $route Route or track root element */ private function readGPXSection(DOMElement $route) { if ($route->tagName == "trk") { $routePoints = $route->getElementsByTagName("trkpt"); } else { $routePoints = $route->getElementsByTagName("rtept"); } /* Now we start to iterate through all the waypoints. * For each point, we want the distance from the last point (added to cumulative * distance) and the height *increase* since the last point. * We assume that the points are close enough together that we can treat the surface * of the Earth as a plane and use Pythagoras' theorem to calculate distances. * To start with, we make the start point the previous point. */ $numPoints = $routePoints->length; $lastKnownHeight = null; // Last known height - used if some nodes are missing height data $prevPoint = null; $iWrite = count($this->wayPoints); for ($iRead = 0; $iRead < $numPoints; $iRead++) { // Get the position of this waypoint $next = $routePoints->item($iRead); $nextPoint = new Waypoint(); $nextPoint->latLng = new LatLng($next->attributes->getNamedItem("lat")->nodeValue, $next->attributes->getNamedItem("lon")->nodeValue); // Now see if we can get the time, speed & altitude if ($next->hasChildNodes()) { foreach ($next->childNodes as $childNode) { if ($childNode->nodeType == XML_ELEMENT_NODE) { switch ($childNode->tagName) { case "ele": $nextPoint->alt = (int) $childNode->nodeValue; break; case "time": $nextPoint->time = $childNode->nodeValue; break; } } } } $this->wayPoints[$iWrite] = $nextPoint; // If we're on anything but the first waypoint, get the previous one for some calculations if ($iWrite >= 1) { $prevPoint = $this->wayPoints[$iWrite - 1]; // Calculate distance & total ascent $this->distance += $nextPoint->distanceTo($prevPoint); if (isset($nextPoint->alt) && isset($lastKnownHeight)) { $this->ascent += max($nextPoint->alt - $lastKnownHeight, 0); } } // Store the height for future rounds - if another waypoint is missing height info // we look back to the last time we had it if (isset($nextPoint->alt)) { $lastKnownHeight = $nextPoint->alt; } $iWrite++; } }
* Northing/Easting: specify as a pair of integer parameters, e.g. ?north=123456&east=123456 * Lat/long: specify as a pair of float parameters, e.g. ?lat=53.21415&lon=-1.52135 * Reverse geocoding searches are done by instansiating a waypoint and using the reverseGeocode() method. * * Postcode: specify as a string. Any spaces will be removed, e.g. ?postcode=S314AF * Location name: specify as a string. String is passed directly to Nominatim, e.g. ?search=Ladybower+inn * Scope: scope can optionally be limited to Sheffield (1), or the general area for walks (2). e.g. ?search=Ladybower+inn&scope=2 TODO: Use constants on some appropriate class * This is only a preference, nominatim will return results outside this area if necessary. * Searches are always limited to the UK. * Location name search is done here for now - may be moved elsewhere when appropriate */ header("Content-type: application/json"); $scopeSheffield = 1; $scopeGeneralArea = 2; if (!empty($_GET['lat']) && !empty($_GET['lon']) || !empty($_GET['east']) && !empty($_GET['north']) || !empty($_GET['gridref'])) { $wp = new Waypoint(); if (!empty($_GET['lat']) && !empty($_GET['lon'])) { $wp->latLng = new LatLng((double) $_GET['lat'], (double) $_GET['lon']); } else { if (!empty($_GET['east']) && !empty($_GET['north'])) { $osRef = new OSRef((int) $_GET['east'], (int) $_GET['north']); $latLng = $osRef->toLatLng(); $latLng->OSGB36ToWGS84(); $wp->latLng = $latLng; } else { if (!empty($_GET['gridref'])) { $osRef = getOSRefFromSixFigureReference($_GET['gridref']); $latLng = $osRef->toLatLng(); $latLng->OSGB36ToWGS84(); $wp->latLng = $latLng; }