# How to add city markers to a map of Germany?

I'm trying to draw markers for a list of Germany ZIP codes onto a map. Following the official documentation, it seems as if using GeoMarkeron values like

Entity["City", {"Nürnberg", "Germany"}]


should work. But Mathematica does not find any location information for German cities:

GeoGraphics[
{GeoMarker[{Entity["City", {"Nürnberg", "Germany"}]}]}
]


Unable to obtain location information for Entity[City,{Nürnberg,Germany}].

I tried several combinations with city names and ZIP codes, but to no avail. But when I search for Nürnberg on Wolframalpha, they clearly have data on the city!

How can I draw markers from ZIP codes in German cities?

Entities are not meant to be typed directly. There is no way to guess the correct format. Instead, type Ctrl-=, type the name of the city in any form you like: Nürnberg or Nuremberg will both work, then hit enter. You'll see this:

If the interpretation is not correct, you can choose another one through the ... menu. If everything if fine, you can confirm with the ✓ button (though this is not compulsory). Now you are ready to use the entity.

If you look at its full form, you will see that it is

Entity["City", {"Nuremberg", "Bavaria", "Germany"}]


The way you entered it was not correct.

The correct form works fine in GeoMarker.

GeoGraphics[
GeoMarker[Entity["City", {"Nuremberg", "Bavaria", "Germany"}]]
]


• Thanks. Unfortunately, this is (in this form) useless when reading about 400 ZIP codes from a CSV. :/ I guess I could, somehow, determine the Bundesland (it's not in the data set; it's irrelevant in Germany for most purposes), but meh. – Raphael Sep 1 '17 at 15:06
• @Raphael Yes, Interpreter is good for that. I showed why your Entity didn't work. – Szabolcs Sep 1 '17 at 17:18
• Whoever downvoted: A downvote won't improve the answer but commenting about what's wrong might. – Szabolcs May 23 '19 at 11:52

## Using an external API

ClearAll[GermanZip2GeoPosition];
GermanZip2GeoPosition[zip_String] := Block[
{response = Quiet@Import[URLBuild[{"https://api.zippopotam.us", "DE", zip}], "RawJSON"]},
If[response =!= \$Failed,
Query["places", 1,
GeoPosition[ToExpression@{#["latitude"], #["longitude"]}] &][response]
, Null
]
];
GermanZip2GeoPosition[zip_Integer] := GermanZip2GeoPosition[ToString[zip]];
SetAttributes[GermanZip2GeoPosition, Listable]


## Example

GeoGraphics@GeoMarker@GermanZip2GeoPosition@{90402, 90491, 90513, 90518, 90522, 90547, 90552, 90579, 90762, 90768
}


Code and plots done in Mathemathica 11.1.1 on Win7

• I like seeing API-based solutions a lot... :D – J. M.'s technical difficulties Sep 1 '17 at 15:53
• Thanks! This seems to work, however the choice of service is probably less than ideal for Germany. As far as I can tell from comparing the images I get, the two versions mostly agree (some markers move a little this way or that) but zippopotam.us does not know a fair number of ZIP codes. – Raphael Sep 1 '17 at 16:58
• @Raphael, if you can find a service that knows German ZIP codes and has an API, we should be able to figure out how to interface Mathematica with it. – J. M.'s technical difficulties Sep 2 '17 at 2:51
• @J.M. Sure, and this answer explains how. I upvoted it, but I felt I needed to leave a "beware caveat" comment for later visitors. – Raphael Sep 2 '17 at 6:52
• @rhermans Oh, I'm sorry I wasn't clear: I didn't expect anybody to program the perfect solution for me. I expect to be able to use any API following your example; and if not, I'd open a new question. I consider this question dealt with; I'll wait another day or two and then accept an answer. Thanks for your help! – Raphael Sep 2 '17 at 7:16

Function Interpreter can find the positions:

Interpreter["Location"]["Nürnberg, Germany"]
Interpreter["Location"]["90402, Germany"]


Both versions return a GeoPosition value.

Starting from a list of ZIP codes, the following works:

plzs := {19258, 57399, 90402}
plzsGermany := Map[ToString[#] <> ", Germany" &, plzs]
positions := Map[Interpreter["Location"][#] &, plzsGermany]
GeoGraphics[
{
GeoStyling["OutlineMap"],
Polygon[Entity["Country", "Germany"]],
GeoMarker[positions]
},
GeoBackground -> Transparent
]


The approach works with city names as well, and should generalize to other countries.

Warning: Applied to long lists of zip codes, this can run a while.

• Beware! Interpreter["Location"] does return GeoPosition from some UK Postcodes, (Interpreter["Location"] ["NW6 1PG"] returns GeoPosition[{51.5472, -0.191049}]) but sometimes fails ( Interpreter["Location"] ["NW6 1EH"] returns failure message "No geographic location interpretation found. Try again"). This was reported in CASE:3913717, the response was that developers "haven't optimized interpreter to handle these inputs. Further conversion of these postal codes to GeoPositions would require a custom interpreter". It may fail for Germany too. – rhermans Sep 1 '17 at 14:16
• @rhermans Yes, some ZIPs failed. Out of the three error messages I got, one was a PO box and two were not even known to Deutsche Post, so I blame my data set. That said, I did add germanPositions := Select[positions, GeoWithinQ[Entity["Country", "Germany"], #] &] to avoid bad/undesired positions. – Raphael Sep 1 '17 at 15:04
• @rhermans Thanks for the warning, anyway! While an approximation of the full data set is fine for my purposes, others may require more precision. – Raphael Sep 1 '17 at 15:04
• At least in the UK, the postal codes that did return GeoPositions were not necessarily accurate. I find it particularly worrisome that this creates the illusion that works, but in reality, translating postal code to GeoPositions is not officially supported, and performance is random. – rhermans Sep 1 '17 at 15:11
• The inaccuracies of GeoPositions I noticed in London UK, was on the order of hundred of meters, not relevant to countrywide scale. – rhermans Sep 1 '17 at 17:59