TopoJson and getting the geography features - Dynamic Object structure

The object you get from a TopoJSON file looks something like this:

{
"type": "Topology",
    "objects": {
        "countries": {
            "type": "GeometryCollection",
            "geometries": [
                {
                    "type": "MultiPolygon",
                    "arcs": [],
                    "id": "242",
                    "properties": {
                        "name": "Fiji"
                    }
                },
                {
                    "type": "Polygon",
                    "arcs": [],
                    "id": "834",
                    "properties": {
                        "name": "Tanzania"
                    }
                },
         ...etc

Using topojson-client, you can extract the geometries with a line something like this:

 geography = feature(worlddata, worlddata.objects.countries).features

The problem is that this case only works for the file found at:
https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json

If you load a different file, the object structure may have a different property name where “countries” is.

To make this dynamic and able to load different TopoJSON files, is there a way to get the property, who in turn has a property “type”: “GeometryCollection”?

Will

You would have to check the JSON and get the correct data you need to pass to the function. How you do it will depend on the difference between the files. If the structure is the same with different key values located at the same position in the files you might be able to use its positional value using Object.keys. I think that gets messy with nested objects so you would likely want some utility function for that (google search).

If the structure is different you can loop the data and look for the property/value and either construct your own object to pass to the function or possibly get the parent property based on the child key/value and then pass that parent object.

Can you post an example of a different file just so we know how it might look?

Here are some other examples:

{
    "type": "Topology",
    "transform": {
        "scale": [
            0.0014366892420870623,
            0.0009809962918089362
        ],
        "translate": [
            -179.174265,
            17.913769
        ]
    },
    "arcs": [],
    "objects": {
        "cb_2015_us_cd114_20m": {
            "type": "GeometryCollection",
            "geometries": [
                {
                    "arcs": [
                        [
                            0,
                            1,
                            2,
                            3,
                            4
                        ]
                    ],
                    "type": "Polygon",
                    "properties": {
                        "STATEFP": "13",
                        "CD114FP": "07",
                        "AFFGEOID": "5001400US1307",
                        "GEOID": "1307",
                        "LSAD": "C2",
                        "CDSESSN": "114",
                        "ALAND": 1016917582,
                        "AWATER": 25618480
                    }
                },
				
				...etc..
			]
		}
	}
}
{
    "type": "Topology",
    "transform": {
        "scale": [
            0.0017671886290226235,
            0.0012462649877817626
        ],
        "translate": [
            -124.40966913141426,
            32.53462647610281
        ]
    },
    "arcs": [],
    "objects": {
        "cb_2015_california_county_20m": {
            "type": "GeometryCollection",
            "geometries": [
                {
                    "arcs": [
                        [
                            0,
                            1,
                            2,
                            3,
                            4,
                            5
                        ]
                    ],
                    "type": "Polygon",
                    "properties": {
                        "STATEFP": "06",
                        "COUNTYFP": "115",
                        "COUNTYNS": "00277322",
                        "AFFGEOID": "0500000US06115",
                        "GEOID": "06115",
                        "NAME": "Yuba",
                        "LSAD": "06",
                        "ALAND": 1636983167,
                        "AWATER": 30986706
                    }
                },
                {
                    "arcs": [
                        [
                            6,
                            7
                        ]
                    ],
                    "type": "Polygon",
                    "properties": {
                        "STATEFP": "06",
                        "COUNTYFP": "075",
                        "COUNTYNS": "00277302",
                        "AFFGEOID": "0500000US06075",
                        "GEOID": "06075",
                        "NAME": "San Francisco",
                        "LSAD": "06",
                        "ALAND": 121455687,
                        "AWATER": 479135404
                    }
                },
				
				...etc...
			 ]
        }
    }
}

Is there always an object with the objects key? Because that narrows it down. If it’s always the first property inside the objects object then it shouldn’t be too hard to use the positional value instead of a known key/name.

Example code with a random object
const users = {
  user1: {
    name: 'John',
    fullName: {
      first: 'John',
      last: 'Doe'
    }
  },
  user2: {
    name: 'Jim',
  },
};

const user1 = users[Object.keys(users)[0]];
console.log(user1);

const user1FullName = user1[Object.keys(user1)[1]]
console.log(user1FullName);

const user1FirstName = user1FullName[Object.keys(user1FullName)[0]]
console.log(user1FirstName);

Edit: BTW, please use the Reply button or an @ with the user name so people get notified when you post. @wzorn

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.