function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Brian KesslerBrian Kessler 

How can I transform GeoJson using Apex?

I'm presently doing the Work with GeoJSON and Create the Map unit of Create a Custom Map for Wave Charts.
Because I'm an SFDC developer, and because my computer isn't presently set up for Python, I'd like to replace the "quick-and-dirty Python script" with an SFDC/Apex solution.

I've created this GeoJsonService class:
public class WAVE_GeoJsonService {
    DB_ContentDocumentSelector contentDocumentSelector;
    DB_ContentVersionSelector contentVersionSelector;
    public WAVE_GeoJsonService(DB_ContentDocumentSelector contentDocumentSelector, DB_ContentVersionSelector contentVersionSelector) {
    	this.contentDocumentSelector = contentDocumentSelector;
    	this.contentVersionSelector = contentVersionSelector;

    public WAVE_GeoJsonService() {
    	this(new DB_ContentDocumentSelector(), new DB_ContentVersionSelector());

    public String zipCodeAreaReformat(String fileName) {
    	Id documentId = contentDocumentSelector.selectByTitle(fileName)[0].id;
    	Blob versionData = contentVersionSelector.selectByContentDocumentId(documentId)[0].VersionData;
    	return this.zipCodeAreaReformat(versionData);
    private String zipCodeAreaReformat(Blob jsonBlob) {
    	Map<String, Object> root = (Map<String, Object>) JSON.deserializeUntyped(jsonBlob.toString());
    	List<Object> featureFromJsonList = (List<Object>) root.get('features');
    	List<WAVE_GeoJsonFeatureModel> featureModelList = new List<WAVE_GeoJsonFeatureModel>();
    	for (Object featureFromJson : featureFromJsonList) {
    		WAVE_GeoJsonFeatureModel featureModel = new WAVE_GeoJsonFeatureModel(featureFromJson); 
    	root.put('features', featureModelList);
    	return JSON.serialize(root);
    public ContentDocument createNewFile() {
    	// TODO:

This can be executed like so:
String json =  (new WAVE_GeoJsonService()).zipCodeAreaReformat('la-zip-code-areas-2012');

As I've determined through System.debug statements (not included), this works as expected UNTIL SFDC needs to serialize root, at which time I get an error like:
UNKNOWN_EXCEPTION: An unexpected error occurred. Please include this ErrorId if you contact support: 524981494-154011 (1095241484)

This also happens if I try to serialize root implicitly in a System.debug statement.

Any ideas what is going wrong and how to fix it?

If it helps, here are the dependencies:
public class WAVE_GeoJsonFeatureModel {
	public String type {get; private set;}
	public Object properties {get; private set;} 
	public Object geometry {get; private set;}
	public String id  {get; private set;}
	public WAVE_GeoJsonFeatureModel(Object featureFromStandardGeoJson) {
		Map<String, Object> attributes = (Map<String, Object>) featureFromStandardGeoJson;
		this.type = (String) attributes.get('type'); = attributes.get('properties');
		this.geometry = attributes.get('geometry'); = (String)((Map<String, Object>) attributes.get('properties')).get('external_id');

public class DB_ContentDocumentSelector {
    public List<ContentDocument> selectByTitle(String fileName) {
    	return [
			SELECT id 
			FROM ContentDocument
			WHERE title = :fileName

public class DB_ContentVersionSelector {
    public List<ContentVersion> selectByContentDocumentId(Id contentDocumentId) {
    	return [
			SELECT versionData
			FROM ContentVersion
			WHERE contentDocumentId = :contentDocumentId
			ORDER BY VersionNumber DESC

Brian KesslerBrian Kessler
Sorry about the excessive whitespace: This edit forum has no "edit" feature.
Also, there is a known transcription error on the WAVE_GeoJsonService.createNewFile() method; it should return null (as a placeholder).