关于操作 SVG 地图的建议

发布于 2024-08-17 20:06:20 字数 1638 浏览 9 评论 0原文

我正在为维基百科绘制加利福尼亚州母语地图。该地图包含每个区域对应一种语言。原始内容如下所示(单击它可查看 SVG):

我想手动为每种语言制作“定位器地图”(在 Inkscape),就像这个,用于一种名为 Cahuilla(语言代码为 cah):

不用说,这样做如果我在 Inkscape 中手动生成所有 60 个字符,那将是一件很痛苦的事情。

更糟糕的是,每当我在原始版本中发现错误时,我就必须重做整套定位器地图。 (事实上​​,我最近意识到我的原件完全缺少一种语言。抱歉 Cupeño。)

所以我的目标是自动化这个过程。我没有太多处理 SVG 甚至 XML 的经验,因此我正在寻找有关哪些库最有帮助的建议。我更喜欢 Python 中的解决方案,因为我对这种语言并不绝望。

总而言之,我需要:

获取原始 SVG 文件中所有语言形状的引用列表。

对于此列表中的每种语言:

  1. 更改当前语言的形状的背景颜色

  2. 在语言周围放置一个框

  3. 复制该框并将其缩放到给定大小(我认识到,在这一步中,可能很难像我在示例中所做的那样实际“裁剪”周围的形状 - 只是创建一个框白色背景上的语言形状就足够了。)

  4. 将副本放在右上角

  5. 将所有这些内容保存在 code.svg 中

最终产品将是 60 个名为 cah.svg 的 SVG 文件,等等。更好的是,如果有必要,可以重新生成整个 shebang编辑原始地图(这很有可能)。

I'm working on a map of the native languages of California for Wikipedia. The map contains areas that each correspond to a language. The original looks like this (click it to see the SVG):

I want to make "locator maps" for each of those individual languages by hand (in Inkscape), like this one, for a language called Cahuilla (which has the language code cah):

Needless to say, doing this would be a pain in the neck if I generated all 60-some by hand in Inkscape.

Worse, whenever I find a mistake in the original, I'd have to redo the whole set of locator maps. (And in fact I recently realized that my original is missing one language entirely. Sorry Cupeño.)

So my goal is to automate this process. I don't have much experience processing SVG or even XML, so I'm looking for recommendations as to which libraries would be most helpful. I'd prefer solutions in Python, sincely I'm not hopeless in that language.

To summarize, I need to:

Get a list of references to all the language shapes in the original SVG file.

For each language in this list:

  1. change the background color of the shape for the current language

  2. put a box around the language

  3. duplicate the box and scale it to a given size (I recognize that in this step it might be difficult to actually "crop" the surrounding shapes as I did in my example -- just creating a box with the language shape on a white background would be sufficient.)

  4. place the duplicate in the upper right corner

  5. save all this stuff in code.svg

The final product will then be 60 SVG files named cah.svg, etc. Better yet, it would be possible to re-generate the whole shebang if it became necessary to edit the original map (which is quite likely).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二手情话 2024-08-24 20:06:20

我建议使用 Python 并专门为 Inkscape 创建扩展。我不认为你真的需要 60 个 SVG,除非你真的想要,因为源地图将拥有你需要的一切。

我要做的就是使用 Inkscape 将各个区域重命名为您将使用的相同语言代码。例如,Cahuilla 或 cah 目前是 SVG 文件中的 path13882。我会将其重命名为 cahCahuilla 并对每个语言区域重复该过程。使用 Edit\XML 编辑器帮助确保更新所有路径。

更新名称/ID 后,您可能会查看 SVG 脚本。我只需创建一个 javascript/ecmascript 地图或字典,其中包含该语言的相关信息:

var langaugeMap = {};
languageMap["cah"] = { name: "Cahuilla", color: "rgb(255, 0, 0)" };
languageMap["cup"] = { name: "Cupeño", color: "rgb(255, 64, 0)" };
// and so on -- this could even be generated from a CSV file or Excel, etc.
// if the highlighted color is always the same, then you don't need it in the map
// or use style sheets for an activeshape and inactiveshape
// Put any information that is specific to a language in the map

然后您只需添加一个鼠标悬停功能即可添加和定位边界框并更改路径颜色。这是事件和脚本的一个示例,尽管它已经过时了。 Carto.net 也有一个交互式地图示例。

SVG 看起来像这样:

<path
   style="fill:#800000;fill-opacity:1;display:inline"
   d="m 422.43078,517.40746 c 0.52151,0.006 1.10755,0.0374 1.75925,0.0825 3.82011,0.26462 5.01088,0.75501 5.75001,2.37491 0.51312,1.12355 2.4121,3.0097 4.22213,4.1946 3.906,2.55656 7.38824,2.07964 9.61517,-1.3194 2.12996,-3.25075 9.13451,-3.19196 13.61739,0.11545 1.77185,1.30707 4.04994,2.38037 5.06319,2.38041 1.01325,0 3.34593,0.92548 5.18421,2.06155 2.52816,1.56236 4.9918,2.09869 10.09889,2.19902 3.71359,0.0729 7.68145,0.64349 8.82374,1.26442 2.81717,1.53202 5.67633,1.42382 10.7693,-0.40133 4.97461,-1.78261 6.31161,-1.36525 17.10267,5.31063 3.39862,2.10239 6.90491,4.08094 7.7956,4.39801 2.46593,0.8776 4.55428,4.66976 3.95259,7.17971 -0.29359,1.22605 -0.75898,3.51121 -1.03349,5.07968 -0.27411,1.56855 -0.88382,3.33952 -1.35761,3.93621 -1.50842,1.89871 -20.98501,7.77151 -27.8945,8.41122 -3.66014,0.33879 -8.3091,1.04337 -10.32987,1.56676 -3.50666,0.90799 -3.81743,0.79746 -6.78388,-2.44089 -3.3486,-3.65594 -6.11308,-4.2716 -8.48815,-1.89661 -2.14408,2.14401 -1.85126,3.96434 1.0667,6.66846 1.40725,1.30409 1.85699,2.10446 1.00027,1.77571 -0.85672,-0.32883 -6.3937,-0.12213 -12.3033,0.46176 -5.9096,0.58386 -12.56062,1.27336 -14.78297,1.53381 -4.17058,0.4888 -5.09869,-0.37014 -2.61673,-2.42989 2.1563,-1.78956 1.74245,-2.63318 -1.65999,-3.36449 -1.69931,-0.36525 -4.94789,-1.90738 -7.213,-3.42496 -2.26473,-1.51754 -5.89662,-3.66823 -8.07583,-4.77731 -2.17921,-1.10923 -6.21922,-3.94186 -8.97721,-6.29463 -4.75318,-4.05478 -4.93682,-4.36681 -3.43604,-6.02527 0.96935,-1.07117 2.36209,-1.56397 3.5899,-1.26992 1.62639,0.38937 2.49494,-0.41237 4.59588,-4.24958 1.42481,-2.60257 2.23686,-4.95457 1.80316,-5.22266 -0.4337,-0.26805 -1.06784,-3.14557 -1.40725,-6.39358 -0.33978,-3.24797 -1.19001,-6.79064 -1.89134,-7.87242 -1.74322,-2.68957 -1.2114,-3.65437 2.44111,-3.61188 l 0,0 z"
   id="cah"
   inkscape:label="#cah"
   onmouseover="highlightRegion(evt);"
   onmouseout="restoreRegion(evt);" />

对于任何使用 SVG 文件的自动化,我将使用 Inkscape 扩展。查看开发者教程/扩展下的 Inkscape wiki。否则,SVG 仍然是 XML,因此如果您在源文件中使用可区分名称命名语言区域,则可以使用 Python 解析 XML 并将每个路径/语言区域保存到单独的文件中。

I would recommend using Python and specifically creating extensions for Inkscape. I don't think you really need 60 SVG unless you really want to because the source map will have everything you need.

What I would do is use Inkscape to rename the various regions to the same language code you will be using. For example, Cahuilla or cah is currently path13882 in your SVG file. I would rename it to cah or Cahuilla and repeat the process for each of the language regions. Use the Edit\XML Editor to help make sure you update all of the paths.

After you have updated the names/IDs, then you might look into SVG scripting. I would just create a javascript/ecmascript map or dictionary that has the relevant information for the language:

var langaugeMap = {};
languageMap["cah"] = { name: "Cahuilla", color: "rgb(255, 0, 0)" };
languageMap["cup"] = { name: "Cupeño", color: "rgb(255, 64, 0)" };
// and so on -- this could even be generated from a CSV file or Excel, etc.
// if the highlighted color is always the same, then you don't need it in the map
// or use style sheets for an activeshape and inactiveshape
// Put any information that is specific to a language in the map

Then you just need to add a mouseover function that would add and position the bounding box and change the path color. Here is one example of events and scripting although it is quite dated. Carto.net has an interactive map example as well.

The SVG would look something like:

<path
   style="fill:#800000;fill-opacity:1;display:inline"
   d="m 422.43078,517.40746 c 0.52151,0.006 1.10755,0.0374 1.75925,0.0825 3.82011,0.26462 5.01088,0.75501 5.75001,2.37491 0.51312,1.12355 2.4121,3.0097 4.22213,4.1946 3.906,2.55656 7.38824,2.07964 9.61517,-1.3194 2.12996,-3.25075 9.13451,-3.19196 13.61739,0.11545 1.77185,1.30707 4.04994,2.38037 5.06319,2.38041 1.01325,0 3.34593,0.92548 5.18421,2.06155 2.52816,1.56236 4.9918,2.09869 10.09889,2.19902 3.71359,0.0729 7.68145,0.64349 8.82374,1.26442 2.81717,1.53202 5.67633,1.42382 10.7693,-0.40133 4.97461,-1.78261 6.31161,-1.36525 17.10267,5.31063 3.39862,2.10239 6.90491,4.08094 7.7956,4.39801 2.46593,0.8776 4.55428,4.66976 3.95259,7.17971 -0.29359,1.22605 -0.75898,3.51121 -1.03349,5.07968 -0.27411,1.56855 -0.88382,3.33952 -1.35761,3.93621 -1.50842,1.89871 -20.98501,7.77151 -27.8945,8.41122 -3.66014,0.33879 -8.3091,1.04337 -10.32987,1.56676 -3.50666,0.90799 -3.81743,0.79746 -6.78388,-2.44089 -3.3486,-3.65594 -6.11308,-4.2716 -8.48815,-1.89661 -2.14408,2.14401 -1.85126,3.96434 1.0667,6.66846 1.40725,1.30409 1.85699,2.10446 1.00027,1.77571 -0.85672,-0.32883 -6.3937,-0.12213 -12.3033,0.46176 -5.9096,0.58386 -12.56062,1.27336 -14.78297,1.53381 -4.17058,0.4888 -5.09869,-0.37014 -2.61673,-2.42989 2.1563,-1.78956 1.74245,-2.63318 -1.65999,-3.36449 -1.69931,-0.36525 -4.94789,-1.90738 -7.213,-3.42496 -2.26473,-1.51754 -5.89662,-3.66823 -8.07583,-4.77731 -2.17921,-1.10923 -6.21922,-3.94186 -8.97721,-6.29463 -4.75318,-4.05478 -4.93682,-4.36681 -3.43604,-6.02527 0.96935,-1.07117 2.36209,-1.56397 3.5899,-1.26992 1.62639,0.38937 2.49494,-0.41237 4.59588,-4.24958 1.42481,-2.60257 2.23686,-4.95457 1.80316,-5.22266 -0.4337,-0.26805 -1.06784,-3.14557 -1.40725,-6.39358 -0.33978,-3.24797 -1.19001,-6.79064 -1.89134,-7.87242 -1.74322,-2.68957 -1.2114,-3.65437 2.44111,-3.61188 l 0,0 z"
   id="cah"
   inkscape:label="#cah"
   onmouseover="highlightRegion(evt);"
   onmouseout="restoreRegion(evt);" />

For any automation with the SVG file, I would use Inkscape extensions. Look at the Inkscape wiki under the Developer Tutorials / Extensions. Otherwise, SVG is still XML so if you have named your language regions in the source file with a distinguishing name, you could use Python to parse the XML and save each path/language region to a separate file.

瀟灑尐姊 2024-08-24 20:06:20

这是使用地图的示例。您可以单击任何元素来获取边界框,这可以用于迷你视图视图框(进行一些调整)。正如您所看到的,它没有向地图添加太多代码,只是添加了几个元素。当您拥有所有 viewBox 时,您可以使用 javascript 动态更新 miniview 'viewBox' 属性。

对于所选形状的着色,我建议在迷你视图 中添加一个 元素,该元素的填充会覆盖在主地图(您可能必须为此使用样式表规则以确保其具有较高的特异性,例如添加 #miniview .activeshape { fill: red !important }。让 <使用>指向选定的形状,并确保在指向的形状上添加class="activeshape"

这至少应该是一个开始,希望它有所帮助:)

Here's an example using your map. You can click any element to get the boundingbox, this can be used for the miniview viewBox (with some tweaking). As you see it's not adding much code to the map, just a couple of elements. When you have all the viewBoxes you can update the miniview 'viewBox' attribute on the fly using javascript.

For the coloring of the selected shape, I'd suggest adding a <use> element inside the miniview <svg> that has a fill that overrides any fill used in the main map (you may have to use a stylesheet rule for this to make sure it's got high specificity, e.g adding #miniview .activeshape { fill: red !important }. Let the <use> point to the selected shape, and make sure you add class="activeshape" on the shape you point to.

This should be a start at least, hope it helps :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文