Source: ogc/openSearch/responseFormats/atomParser/OpenSearchGeoRssParser.js

/*
 * Copyright 2003-2006, 2009, 2017, United States Government, as represented by the Administrator of the
 * National Aeronautics and Space Administration. All rights reserved.
 *
 * The NASAWorldWind/WebWorldWind platform is licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @exports OpenSearchGeoRssParser
 */

define([
        '../../OpenSearchNamespaces',
        '../../OpenSearchUtils'
    ],
    function (OpenSearchNamespaces,
              OpenSearchUtils) {
        'use strict';

        /**
         * Parses GeoRSS and converts it to GeoJSON.
         *
         * The Simple and GML encoding of GeoRSS are supported.
         *
         * @exports OpenSearchGeoRssParser
         */
        var OpenSearchGeoRssParser = {

            /**
             * Parses the specified GeoRSS-Simple node as a GeoJSON geometry.
             *
             * @param {Node} node The GeoRSS node.
             *
             * @return {Object} The resulting GeoJSON geometry.
             */
            parseSimple: function (node) {
                var geometry = {
                    type: '',
                    coordinates: []
                };

                if (node.localName === 'polygon') {
                    geometry.type = 'Polygon';
                    geometry.coordinates.push(OpenSearchGeoRssParser.parseLocations(node));
                }
                else if (node.localName === 'point') {
                    geometry.type = 'Point';
                    geometry.coordinates = OpenSearchGeoRssParser.parseLocations(node);
                }
                else if (node.localName === 'line') {
                    geometry.type = 'LineString';
                    geometry.coordinates = OpenSearchGeoRssParser.parseLocations(node);
                }

                return geometry;
            },

            /**
             * Parses the specified GeoRSS-GML node as a GeoJSON geometry.
             *
             * @param {Node} node The GeoRSS node.
             *
             * @return {Object} The resulting GeoJSON geometry.
             */
            parseGml: function (node) {
                var geometry = {
                    type: '',
                    coordinates: []
                };
                var firstChild = node.firstElementChild;

                switch (firstChild.localName) {
                    case 'Point':
                        geometry.type = 'Point';
                        var posNode = OpenSearchUtils.getXmlElements(firstChild, 'pos')[0];
                        if (posNode) {
                            geometry.coordinates = OpenSearchGeoRssParser.parseLocations(posNode);
                        }
                        break;

                    case 'LineString':
                        geometry.type = 'LineString';
                        var posList = OpenSearchUtils.getXmlElements(firstChild, 'posList')[0];
                        if (posList) {
                            geometry.coordinates = OpenSearchGeoRssParser.parseLocations(posList);
                        }
                        break;

                    case 'Polygon':
                        geometry.type = 'Polygon';
                        geometry.coordinates = OpenSearchGeoRssParser.parseGmlPolygon(firstChild);
                        break;

                    case 'MultiSurface':
                        geometry.type = 'MultiPolygon';
                        geometry.coordinates = [OpenSearchGeoRssParser.parseMultiPolygon(firstChild)];
                        break;

                    default:
                        break;
                }

                return geometry;
            },

            /**
             * Parses the specified GeoRSS box node as GeoJSON bounding box.
             *
             * @param {Node} node The GeoRSS box node.
             *
             * @return {Array} The resulting GeoJSON bounding box.
             */
            parseBox: function (node) {
                var locations = OpenSearchGeoRssParser.parseLocations(node);
                return [].concat.apply([], locations);
            },

            /**
             * Extracts the coordinates of the specified GeoRSS node as a GeoJSON coordinates array.
             *
             * @param {Node} node The GeoRSS node.
             *
             * @return {Array} The resulting GeoJSON coordinates array.
             */
            parseLocations: function (node) {
                var points = node.textContent.trim().replace(/\s+/g, ' ').split(' ');
                var locations = [];
                for (var i = 0; i < points.length; i += 2) {
                    var lat = +points[i];
                    var lon = +points[i + 1];
                    locations.push([lon, lat]);
                }
                return locations;
            },

            /**
             * Extracts the coordinates of the specified GeoRSS-GML Polygon node as a GeoJSON coordinates array.
             *
             * @param {Node} node The GeoRSS-GML Polygon node.
             *
             * @return {Array} The resulting GeoJSON coordinates array.
             */
            parseGmlPolygon: function (node) {
                var exteriorPosList = OpenSearchUtils.getXmlElements(node, 'posList')[0];
                var interiorNodes = OpenSearchUtils.getXmlElements(node, 'interior');

                var exteriorLocations = OpenSearchGeoRssParser.parseLocations(exteriorPosList);

                var interiors = [];
                for (var i = 0; i < interiorNodes.length; i++) {
                    var interiorPosList = OpenSearchUtils.getXmlElements(interiorNodes[i], 'posList')[0];
                    if (interiorPosList) {
                        var interiorLocations = OpenSearchGeoRssParser.parseLocations(interiorPosList);
                        interiors.push(interiorLocations);
                    }
                }

                return exteriorLocations.concat(interiors);
            },

            /**
             * Extracts the coordinates of the specified GeoRSS-GML MultiSurface node as a GeoJSON coordinates array.
             *
             * @param {Node} node The GeoRSS-GML MultiSurface node.
             *
             * @return {Array} The resulting GeoJSON coordinates array.
             */
            parseMultiPolygon: function (node) {
                //node can contain a single 'surfaceMembers' element and/or multiple 'surfaceMember' elements

                var polygons = OpenSearchUtils.getXmlElements(node, 'surfaceMember').map(function (surfaceMember) {
                    return OpenSearchUtils.getXmlElements(surfaceMember, 'Polygon');
                });

                var surfaceMembers = OpenSearchUtils.getXmlElements(node, 'surfaceMembers')[0];
                if (surfaceMembers) {
                    polygons = polygons.concat(OpenSearchUtils.getXmlElements(surfaceMembers, 'Polygon'));
                }

                return polygons.map(function (polygon) {
                    return OpenSearchGeoRssParser.parseGmlPolygon(polygon);
                });
            }

        };

        return OpenSearchGeoRssParser;
    });