Topic: ParseOSMResponse and area elements

In trying to replicate the functionality of the Query Features button on OSM, I've discovered an operator that yields an element that's not currently supported by OSM. I'm going to add a version of it myself, but I thought you might want to see if you'd like to add it to the standard distribution.

If you go to http://overpass-turbo.eu/ and paste in the following query

is_in(34.17288, -118.5042);(._;>;);out meta;

you won't see anything on the map, but if you open up the Data display, you'll see a number of elements like this

  <area id="2716623880">
    <tag k="ele" v="217"/>
    <tag k="leisure" v="park"/>
    <tag k="name" v="Balboa Sports Center"/>
  </area>

Currently, ParseOSMResponse only works with nodes, ways, and relations. Looking at the code for that procedure, it seems like it won't be too difficult for me to write a new procedure modeled on those that also includes support for area elements. Once I get it working reliably, I'll post it for you to check out and let me know if there are any errors not obvious to me, and to decide if it's something you'd like to add to the base code.

Thanks again for your sterling support! smile

Re: ParseOSMResponse and area elements

Here's the class for OnlineMapsOSMArea. It's basically OnlineMapsOSMNode with the lat/long stripped away and the name changed.

/// <summary>
/// Open Street Map area element class
/// </summary>
public class OnlineMapsOSMArea : OnlineMapsOSMBase
{

    public OnlineMapsOSMArea(OnlineMapsOSMAPIQuery.OSMXMLNode node)
    {
        id = node.GetAttribute("id");
    }

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="node">Node</param>
    public OnlineMapsOSMArea(OnlineMapsXML node)
    {
        id = node.A("id");

        tags = new List<OnlineMapsOSMTag>(node.count);

        foreach (OnlineMapsXML subNode in node) tags.Add(new OnlineMapsOSMTag(subNode));
    }

}

And here's the changed versions of the two ParseOSMResponse routines.

    /// <summary>
    /// Get data from the response Open Street Map Overpass API.
    /// </summary>
    /// <param name="response">Response from Overpass API</param>
    /// <param name="nodes">List of nodes</param>
    /// <param name="ways">List of ways</param>
    /// <param name="relations">List of relations</param>
    public static void ParseOSMResponse(string response, out List<OnlineMapsOSMNode> nodes, out List<OnlineMapsOSMWay> ways, out List<OnlineMapsOSMRelation> relations, out List<OnlineMapsOSMArea> areas)
    {
        nodes = new List<OnlineMapsOSMNode>();
        ways = new List<OnlineMapsOSMWay>();
        relations = new List<OnlineMapsOSMRelation>();
        areas = new List<OnlineMapsOSMArea>();

        try
        {
            OnlineMapsXML xml = OnlineMapsXML.Load(response);

            foreach (OnlineMapsXML node in xml)
            {
                if (node.name == "node") nodes.Add(new OnlineMapsOSMNode(node));
                else if (node.name == "way") ways.Add(new OnlineMapsOSMWay(node));
                else if (node.name == "relation") relations.Add(new OnlineMapsOSMRelation(node));
                else if (node.name == "area") areas.Add(new OnlineMapsOSMArea(node));
            }
        }
        catch
        {
            Debug.Log(response);
        }
    }

    /// <summary>
    /// Get data from the response Open Street Map Overpass API.
    /// </summary>
    /// <param name="response">Response from Overpass API</param>
    /// <param name="nodes">Dictionary of nodes</param>
    /// <param name="ways">List of ways</param>
    /// <param name="relations">List of relations</param>
    public static void ParseOSMResponse(string response, out Dictionary<string, OnlineMapsOSMNode> nodes, out List<OnlineMapsOSMWay> ways, out List<OnlineMapsOSMRelation> relations, out List<OnlineMapsOSMArea> areas)
    {
        nodes = new Dictionary<string, OnlineMapsOSMNode>(64);
        ways = new List<OnlineMapsOSMWay>(64);
        relations = new List<OnlineMapsOSMRelation>(64);
        areas = new List<OnlineMapsOSMArea>(64);  // why do we specify a length of 64 here but not in the other ParseOSMResponse?

        try
        {
            OnlineMapsXML xml = OnlineMapsXML.Load(response);

            foreach (OnlineMapsXML node in xml)
            {
                if (node.name == "node")
                {
                    OnlineMapsOSMNode osmNode = new OnlineMapsOSMNode(node);
                    nodes.Add(osmNode.id, osmNode);
                }
                else if (node.name == "way")
                {
                    ways.Add(new OnlineMapsOSMWay(node));
                }
                else if (node.name == "relation")
                {
                    relations.Add(new OnlineMapsOSMRelation(node));
                }
                else if (node.name == "area")
                {
                    areas.Add(new OnlineMapsOSMArea(node));
                }
            }
        }
        catch
        {
            Debug.Log(response);
        }
    }

I didn't implement the change in ParseOSMResponseFast because that was a bit more involved, but you might want to if you decide to incorporate area elements into the base code. Also, a quick question you might have noticed in a comment in the code- why in the overload that uses a Dictionary for the nodes do you set both Dictionary and Lists to a size of 64 when declaring them? Just curious.

I've tested the code here and it appears to be functional. I would love it if you were to incorporate it, as it might be useful to others, and it would keep me from having to pull it out into its own script inheriting from OnlineMapsOSMAPIQuery so as not to get overwritten whenever I update your code.

Thanks again, and I hope this proves useful, especially considering how much example code you provide to those using your asset.

Re: ParseOSMResponse and area elements

Hello.

We added these methods into Online Maps.
The new version is already available through the built-in update system.

We will not add this into ParseOSMResponseFast, because this method is only for buildings, and its main task is to be as fast as possible. That's why it ignores most of XML standard, and can not be used for other tasks.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: ParseOSMResponse and area elements

Yay! Happy to be a part of moving this awesome asset forward. big_smile