/*
|
* Licensed to the Apache Software Foundation (ASF) under one
|
* or more contributor license agreements. See the NOTICE file
|
* distributed with this work for additional information
|
* regarding copyright ownership. The ASF licenses this file
|
* to you under the Apache License, Version 2.0 (the
|
* "License"); you may not use this file except in compliance
|
* with the License. You may obtain a copy of the License at
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing,
|
* software distributed under the License is distributed on an
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
* KIND, either express or implied. See the License for the
|
* specific language governing permissions and limitations
|
* under the License.
|
*/
|
|
import {parseSVG, makeViewBoxTransform} from 'zrender/src/tool/parseSVG';
|
import Group from 'zrender/src/container/Group';
|
import Rect from 'zrender/src/graphic/shape/Rect';
|
import {assert, createHashMap} from 'zrender/src/core/util';
|
import BoundingRect from 'zrender/src/core/BoundingRect';
|
import {makeInner} from '../../util/model';
|
|
var inner = makeInner();
|
|
export default {
|
|
/**
|
* @param {string} mapName
|
* @param {Object} mapRecord {specialAreas, geoJSON}
|
* @return {Object} {root, boundingRect}
|
*/
|
load: function (mapName, mapRecord) {
|
var originRoot = inner(mapRecord).originRoot;
|
if (originRoot) {
|
return {
|
root: originRoot,
|
boundingRect: inner(mapRecord).boundingRect
|
};
|
}
|
|
var graphic = buildGraphic(mapRecord);
|
|
inner(mapRecord).originRoot = graphic.root;
|
inner(mapRecord).boundingRect = graphic.boundingRect;
|
|
return graphic;
|
},
|
|
makeGraphic: function (mapName, mapRecord, hostKey) {
|
// For performance consideration (in large SVG), graphic only maked
|
// when necessary and reuse them according to hostKey.
|
var field = inner(mapRecord);
|
var rootMap = field.rootMap || (field.rootMap = createHashMap());
|
|
var root = rootMap.get(hostKey);
|
if (root) {
|
return root;
|
}
|
|
var originRoot = field.originRoot;
|
var boundingRect = field.boundingRect;
|
|
// For performance, if originRoot is not used by a view,
|
// assign it to a view, but not reproduce graphic elements.
|
if (!field.originRootHostKey) {
|
field.originRootHostKey = hostKey;
|
root = originRoot;
|
}
|
else {
|
root = buildGraphic(mapRecord, boundingRect).root;
|
}
|
|
return rootMap.set(hostKey, root);
|
},
|
|
removeGraphic: function (mapName, mapRecord, hostKey) {
|
var field = inner(mapRecord);
|
var rootMap = field.rootMap;
|
rootMap && rootMap.removeKey(hostKey);
|
if (hostKey === field.originRootHostKey) {
|
field.originRootHostKey = null;
|
}
|
}
|
};
|
|
function buildGraphic(mapRecord, boundingRect) {
|
var svgXML = mapRecord.svgXML;
|
var result;
|
var root;
|
|
try {
|
result = svgXML && parseSVG(svgXML, {
|
ignoreViewBox: true,
|
ignoreRootClip: true
|
}) || {};
|
root = result.root;
|
assert(root != null);
|
}
|
catch (e) {
|
throw new Error('Invalid svg format\n' + e.message);
|
}
|
|
var svgWidth = result.width;
|
var svgHeight = result.height;
|
var viewBoxRect = result.viewBoxRect;
|
|
if (!boundingRect) {
|
boundingRect = (svgWidth == null || svgHeight == null)
|
// If svg width / height not specified, calculate
|
// bounding rect as the width / height
|
? root.getBoundingRect()
|
: new BoundingRect(0, 0, 0, 0);
|
|
if (svgWidth != null) {
|
boundingRect.width = svgWidth;
|
}
|
if (svgHeight != null) {
|
boundingRect.height = svgHeight;
|
}
|
}
|
|
if (viewBoxRect) {
|
var viewBoxTransform = makeViewBoxTransform(viewBoxRect, boundingRect.width, boundingRect.height);
|
var elRoot = root;
|
root = new Group();
|
root.add(elRoot);
|
elRoot.scale = viewBoxTransform.scale;
|
elRoot.position = viewBoxTransform.position;
|
}
|
|
root.setClipPath(new Rect({
|
shape: boundingRect.plain()
|
}));
|
|
return {
|
root: root,
|
boundingRect: boundingRect
|
};
|
}
|