• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
5

SVG renders differently in Illustrator vs web browsers

Community Beginner ,
Nov 16, 2023 Nov 16, 2023

Copy link to clipboard

Copied

I've created an SVG from a geojson via a Python script using svgwrite. The exported SVG file renders properly in web browsers (Safari, FireFox, Chrome, ect) but does not look correct in Adobe Illustrator. Specifically, not all of the polygons from the geojson are drawn in Illustrator. I checked using the W3C Validator, and the SVG appears to look OK. Any ideas as to what's happening here?

Link to the SVG, also attached to this post. 

 

Below is the SVG rendered in a web browser:
Screen Shot 2023-11-16 at 2.04.04 PM.png

 

 The SVG rendered in Illustrator:

Screen Shot 2023-11-16 at 1.58.32 PM.png

Here's the code that genereated the SVG:

 

import svgwrite
import geopandas
from dotenv import dotenv_values
from os import listdir
from os.path import isfile, join


class Map:
    def __init__(self, name:str, scale:int=1, epsg:str='2163'):
        self.name = name
        self.base_path = dotenv_values(".env")["FILE_PATH"]
        self.scale = scale
        self.epsg = epsg
        self.data_path = join(self.base_path, self.name)
        self.gdfs = self.get_gdfs()
        self.minx, self.miny, self.maxx, self.maxy = self.get_bounds()
        self.dwg = self.init_drawing()

    def get_gdfs(self) -> list:
        print(self.data_path)
        gdfs = []
        for file in listdir(self.data_path):
            if file.endswith('.geojson'):
                gdf = geopandas.read_file(join(self.data_path, file))
                gdfs.append({
                    'name': file.split('.')[0],
                    'gdf': gdf.to_crs(f'epsg:{self.epsg}')
                })
        return gdfs

    def get_bounds(self):
        minx = miny = maxx = maxy = 0
        for gdf in self.gdfs:
            _minx, _miny, _maxx, _maxy = [x * self.scale for x in gdf['gdf'].total_bounds]
            minx = _minx if _minx < minx else minx
            miny = _miny if _miny < miny else miny
            maxx = _maxx if _maxx > maxx else maxx
            maxy = _maxy if _maxy > maxy else maxy
        return [minx, miny, maxx, maxy]

    def get_viewbox(self):
        return f'0 {0 - (self.maxy - self.miny)} {self.maxx - self.minx} {self.maxy - self.miny}'

    def init_drawing(self):
        return svgwrite.Drawing(
            f'{self.base_path}/{self.name}.svg',
            height='100%',
            width='100%',
            viewBox=self.get_viewbox(),
            id='map'
        )

    def trans(self, coord: float, type: str):
        if type == 'x':
            m = (coord * self.scale) - self.minx
        if type == 'y':
            m = 0 - (coord * self.scale - self.miny)
        return round(m, 4)

    def add_path(self, coords: list, lyr):
        data = [f"{(self.trans(x, 'x'))} {self.trans(y, 'y')}" for x, y in coords]
        path_data = "M " + " ".join(data) + " Z"
        path = self.dwg.path(
            d=path_data,
        )
        path.scale(self.scale)
        lyr.add(path)

    def add_layer(self, gdf):
        lyr = svgwrite.container.Group(class_=gdf['name'], id=gdf['name'])
        for feature in gdf['gdf'].iterrows():
            if 'name' in feature[1]:
                group = svgwrite.container.Group(id=name.replace(' ', '-'))
            else:
                group = svgwrite.container.Group()
            name = 'feature' if 'name' not in feature[1] else feature[1]['name']
            print(feature)
            geometry = feature[1]['geometry']
            if geometry.geom_type == 'Polygon':
                coordinates = geometry.exterior.coords
                self.add_path(coordinates, group)
            if geometry.geom_type == 'MultiPolygon':
                coordinates_list = [list(x.exterior.coords) for x in geometry.geoms]
                for coordinates in coordinates_list:
                    self.add_path(coordinates, group)
            lyr.add(group)
        self.dwg.add(lyr)

    def save(self):
        for gdf in self.gdfs:
            self.add_layer(gdf)
        self.dwg.save()

map = Map('north-america')
map.save()

 

SVG Code Excerpt:

 

<?xml version="1.0" encoding="utf-8"?>
<svg baseProfile="full" height="100%" id="map" version="1.1"
  viewBox="0 -5970769 6238439 5970769" width="100%"
  xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs />
  <g class="example-ranges" id="example-ranges">
    <path
      d="M 3105142.9506 -32938.6211 3094302.0224 -55180.2184 3087064.7285 -71713.278 3083023.7257 -82910.1436 3077742.3081 -92125.3977 3075637.6998 -96798.1838 3073004.9855 -99981.1093 3069727.7491 -102145.3881 3067417.1429 -103646.6451 3062078.0695 -103681.8678 3058193.7701 -102357.0232 3058289.4769 -100060.4703 3056614.3077 -99070.8656 3055978.9745 -79024.0893 3056365.7161 -63845.524 3054521.8344 -61724.582 3052682.3899 -58166.3599 3052034.982 -56066.8608 3050956.097 -52567.4711 3049575.3355 -50437.383 3049661.4522 -24864.9451 3051467.61 -22634.6884 3053977.8979 -21125.0244 3058801.1988 -16944.8917 3061152.127 -13353.6409 3064178.4849 -11173.6045 3068575.4161 -11356.2774 3074532.3332 -9298.3574 3078629.532 -7296.0449 3083269.1544 -5050.691 3092407.102 -4267.8405 3103568.6482 -5121.7845 3105142.9506 -32938.6211 Z" />
    <path
      d="M 3031630.1111 -196686.7707 3024334.0946 -198958.4428 3017595.1924 -203032.9032 3003786.6803 -204054.8141 3001343.6298 -201778.063 3001409.7627 -185564.694 3003357.8919 -174763.7179 3005708.8461 -169319.2759 3011607.3284 -165008.2374 3018467.6138 -162913.5004 3026231.6627 -164418.5914 3034477.2638 -164558.9579 3038479.7485 -159973.6944 3043334.3581 -155225.2776 3051830.7676 -154388.1375 3061332.9853 -154781.2864 3064116.1069 -159053.3257 3067955.731 -163368.9042 3067373.294 -187482.2938 3062778.647 -191049.5923 3057329.5235 -194779.2478 3054465.6944 -197429.3134 3046230.8649 -196891.6727 3042543.3594 -193971.2508 3037056.6788 -193547.8044 3031630.1111 -196686.7707 Z" />
    <path
      d="M 4861989.6231 -483370.5556 4858819.9277 -483156.6887 4857251.5424 -480416.6511 4854081.7307 -480203.1023 4852513.398 -477463.3235 4854114.7316 -474936.6986 4852546.302 -472196.7832 4849376.6847 -471983.887 4847808.3049 -469244.2286 4849409.3967 -466717.0718 4847840.9214 -463977.2752 4849441.5997 -461449.6458 4852610.5811 -461661.8727 4854179.2027 -464402.0636 4857348.0627 -464614.6057 4858916.7345 -467355.0532 4862085.4774 -467567.91 4863654.2025 -470308.6145 4866822.8232 -470521.7872 4868391.5967 -473262.7505 4866791.604 -475790.146 4868360.2796 -478530.974 4871529.0931 -478744.8017 4873097.8149 -481485.8903 4871497.5785 -484012.7558 4868328.4487 -483798.5895 4866759.8717 -481057.8963 4863590.6169 -480844.0481 4861989.6231 -483370.5556 Z" />
     ...
  </g>  
</svg>

 

 

TOPICS
Bug , Draw and design , Import and export , Performance , Scripting

Views

502

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Nov 16, 2023 Nov 16, 2023

It looks like just the largest path is missing. Do you know how many points that path consists of? If it's over 32,000, Illustrator may disregard it as that's it's limit.

Votes

Translate

Translate
Adobe
Community Expert ,
Nov 16, 2023 Nov 16, 2023

Copy link to clipboard

Copied

It looks like just the largest path is missing. Do you know how many points that path consists of? If it's over 32,000, Illustrator may disregard it as that's it's limit.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 16, 2023 Nov 16, 2023

Copy link to clipboard

Copied

@Doug A Roberts 
That might be it! The largest path is 48,771 points. Is there a way to change the limit of points for a path?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 19, 2023 Nov 19, 2023

Copy link to clipboard

Copied

LATEST

AI is a 30yo app and its limitations are baked in deep. (e.g. Pasteboard and font sizes are also limited.)

 

Affinity Designer 2 opens the SVG without problem (except it can’t zoom out far enough to fit the entire thing on screen: AfD reports it as 4km²!).

 

I’ve attached a copy with the long path split in half so it now shows up in AI. Depending on what you’re using this artwork for, simplifying that monster path would be a very good idea.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 16, 2023 Nov 16, 2023

Copy link to clipboard

Copied

Is it possible to simplify the points on the GeoJSON side?

 

I often use the geo2topo command to convert from GeoJSON to TopoJSON through the simplification process. The result is a clean path that is easy to use in Illustrator.

 

I have never used this service, but it seems to be possible to simplify it with a service called mapshaper.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Nov 16, 2023 Nov 16, 2023

Copy link to clipboard

Copied

`geopandas` and `shapely` have a nice `simplify` function which should work for this use case. Mapshaper is such a gem for quick geojson editing though. 

Thanks so much! 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines