Browse Source

merge with upstream

pull/1437/head
ShvaykaD 8 years ago
parent
commit
4d894ea404
  1. 4
      application/pom.xml
  2. 13
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  3. 9
      application/src/main/java/org/thingsboard/server/service/encoding/ProtoWithFSTService.java
  4. 2
      application/src/main/scripts/install/install_dev_db.sh
  5. 2
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java
  6. 2
      dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java
  7. 26
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  8. 12
      dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java
  9. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java
  10. 83
      dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java
  11. 12
      pom.xml
  12. 38
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java
  13. 3
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
  14. 45
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java
  15. 11
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java
  16. 1
      ui/src/app/entity/entity-subtype-autocomplete.directive.js
  17. 2
      ui/src/app/entity/entity-subtype-autocomplete.tpl.html
  18. 1581
      ui/src/app/locale/locale.constant-de_DE.json
  19. 7
      ui/src/app/locale/locale.constant-en_US.json
  20. 5
      ui/src/app/locale/locale.constant-es_ES.json
  21. 3
      ui/src/app/locale/locale.constant-fr_FR.json
  22. 21
      ui/src/app/locale/locale.constant-it_IT.json
  23. 21
      ui/src/app/locale/locale.constant-ja_JA.json
  24. 8
      ui/src/app/locale/locale.constant-ko_KR.json
  25. 5
      ui/src/app/locale/locale.constant-ru_RU.json
  26. 3
      ui/src/app/locale/locale.constant-tr_TR.json
  27. 7
      ui/src/app/locale/locale.constant-zh_CN.json
  28. 42
      ui/src/app/widget/lib/google-map.js
  29. 15
      ui/src/app/widget/lib/image-map.js
  30. 2251
      ui/src/app/widget/lib/map-widget2.js
  31. 494
      ui/src/app/widget/lib/openstreet-map.js
  32. 786
      ui/src/app/widget/lib/tencent-map.js

4
application/pom.xml

@ -41,6 +41,10 @@
</properties>
<dependencies>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>

13
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -92,6 +92,19 @@ public class AlarmController extends BaseController {
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.DELETE)
@ResponseBody
public Boolean deleteAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
return alarmService.deleteAlarm(getTenantId(), alarmId);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)

9
application/src/main/java/org/thingsboard/server/service/encoding/ProtoWithJavaSerializationDecodingEncodingService.java → application/src/main/java/org/thingsboard/server/service/encoding/ProtoWithFSTService.java

@ -17,8 +17,8 @@ package org.thingsboard.server.service.encoding;
import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.nustaq.serialization.FSTConfiguration;
import org.springframework.stereotype.Service;
import org.springframework.util.SerializationUtils;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
@ -30,13 +30,14 @@ import static org.thingsboard.server.gen.cluster.ClusterAPIProtos.MessageType.CL
@Slf4j
@Service
public class ProtoWithJavaSerializationDecodingEncodingService implements DataDecodingEncodingService {
public class ProtoWithFSTService implements DataDecodingEncodingService {
private final FSTConfiguration config = FSTConfiguration.createDefaultConfiguration();
@Override
public Optional<TbActorMsg> decode(byte[] byteArray) {
try {
TbActorMsg msg = (TbActorMsg) SerializationUtils.deserialize(byteArray);
TbActorMsg msg = (TbActorMsg) config.asObject(byteArray);
return Optional.of(msg);
} catch (IllegalArgumentException e) {
@ -47,7 +48,7 @@ public class ProtoWithJavaSerializationDecodingEncodingService implements DataDe
@Override
public byte[] encode(TbActorMsg msq) {
return SerializationUtils.serialize(msq);
return config.asByteArray(msq);
}
@Override

2
application/src/main/scripts/install/install_dev_db.sh

@ -28,7 +28,7 @@ export LOADER_PATH=${BASE}/conf,${BASE}/extensions
export SQL_DATA_FOLDER=${SQL_DATA_FOLDER:-/tmp}
run_user=thingsboard
run_user="$USER"
sudo -u "$run_user" -s /bin/sh -c "java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \
-Dinstall.data_dir=${installDir} \

2
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmDao.java

@ -31,6 +31,8 @@ import java.util.UUID;
*/
public interface AlarmDao extends Dao<Alarm> {
Boolean deleteAlarm(TenantId tenantId, Alarm alarm);
ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, UUID key);

2
dao/src/main/java/org/thingsboard/server/dao/alarm/AlarmService.java

@ -35,6 +35,8 @@ public interface AlarmService {
Alarm createOrUpdateAlarm(Alarm alarm);
Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId);
ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs);
ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long ackTs);

26
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java

@ -24,6 +24,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmId;
@ -118,6 +119,21 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
return alarmDao.findLatestByOriginatorAndType(tenantId, originator, type);
}
@Override
public Boolean deleteAlarm(TenantId tenantId, AlarmId alarmId) {
try {
log.debug("Deleting Alarm Id: {}", alarmId);
Alarm alarm = alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()).get();
if (alarm == null) {
return false;
}
deleteEntityRelations(tenantId, alarm.getId());
return alarmDao.deleteAlarm(tenantId, alarm);
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
}
private Alarm createAlarm(Alarm alarm) throws InterruptedException, ExecutionException {
log.debug("New Alarm : {}", alarm);
Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
@ -127,9 +143,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
private void createAlarmRelations(Alarm alarm) throws InterruptedException, ExecutionException {
if (alarm.isPropagate()) {
EntityRelationsQuery query = new EntityRelationsQuery();
query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE));
List<EntityId> parentEntities = relationService.findByQuery(alarm.getTenantId(), query).get().stream().map(EntityRelation::getFrom).collect(Collectors.toList());
List<EntityId> parentEntities = getParentEntities(alarm);
for (EntityId parentId : parentEntities) {
createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId(), alarm.getStatus(), true);
}
@ -137,6 +151,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
createAlarmRelation(alarm.getTenantId(), alarm.getOriginator(), alarm.getId(), alarm.getStatus(), true);
}
private List<EntityId> getParentEntities(Alarm alarm) throws InterruptedException, ExecutionException {
EntityRelationsQuery query = new EntityRelationsQuery();
query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE));
return relationService.findByQuery(alarm.getTenantId(), query).get().stream().map(EntityRelation::getFrom).collect(Collectors.toList());
}
private ListenableFuture<Alarm> updateAlarm(Alarm update) {
alarmDataValidator.validate(update, Alarm::getTenantId);
return getAndUpdate(update.getTenantId(), update.getId(), new Function<Alarm, Alarm>() {

12
dao/src/main/java/org/thingsboard/server/dao/alarm/CassandraAlarmDao.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.dao.alarm;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;
import com.google.common.util.concurrent.Futures;
@ -78,6 +79,17 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al
return super.save(tenantId, alarm);
}
@Override
public Boolean deleteAlarm(TenantId tenantId, Alarm alarm) {
Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, alarm.getId().getId()))
.and(eq(ALARM_TENANT_ID_PROPERTY, tenantId.getId()))
.and(eq(ALARM_ORIGINATOR_ID_PROPERTY, alarm.getOriginator().getId()))
.and(eq(ALARM_ORIGINATOR_TYPE_PROPERTY, alarm.getOriginator().getEntityType()))
.and(eq(ALARM_TYPE_PROPERTY, alarm.getType()));
log.debug("Remove request: {}", delete.toString());
return executeWrite(tenantId, delete).wasApplied();
}
@Override
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
Select select = select().from(ALARM_COLUMN_FAMILY_NAME);

5
dao/src/main/java/org/thingsboard/server/dao/sql/alarm/JpaAlarmDao.java

@ -68,6 +68,11 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
return alarmRepository;
}
@Override
public Boolean deleteAlarm(TenantId tenantId, Alarm alarm) {
return removeById(tenantId, alarm.getUuidId());
}
@Override
public ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type) {
return service.submit(() -> {

83
dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java

@ -31,7 +31,9 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import java.util.List;
import java.util.concurrent.ExecutionException;
public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
@ -184,4 +186,85 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest {
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, alarms.getData().get(0));
}
@Test
public void testDeleteAlarm() throws ExecutionException, InterruptedException {
AssetId parentId = new AssetId(UUIDs.timeBased());
AssetId childId = new AssetId(UUIDs.timeBased());
EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE);
Assert.assertTrue(relationService.saveRelationAsync(tenantId, relation).get());
long ts = System.currentTimeMillis();
Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId)
.type(TEST_ALARM)
.propagate(true)
.severity(AlarmSeverity.CRITICAL).status(AlarmStatus.ACTIVE_UNACK)
.startTs(ts).build();
Alarm created = alarmService.createOrUpdateAlarm(alarm);
TimePageData<AlarmInfo> alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.affectedEntityId(childId)
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0L, System.currentTimeMillis(), false)
).build()).get();
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, alarms.getData().get(0));
// Check parent relation
alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.affectedEntityId(parentId)
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0L, System.currentTimeMillis(), false)
).build()).get();
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(1, alarms.getData().size());
Assert.assertEquals(created, alarms.getData().get(0));
List<EntityRelation> toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM);
Assert.assertEquals(8, toAlarmRelations.size());
List<EntityRelation> fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
Assert.assertEquals(4, fromChildRelations.size());
List<EntityRelation> fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
Assert.assertEquals(4, fromParentRelations.size());
Assert.assertTrue("Alarm was not deleted when expected", alarmService.deleteAlarm(tenantId, created.getId()));
Alarm fetched = alarmService.findAlarmByIdAsync(tenantId, created.getId()).get();
Assert.assertNull("Alarm was returned when it was expected to be null", fetched);
alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.affectedEntityId(childId)
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0L, System.currentTimeMillis(), false)
).build()).get();
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
// Check parent relation
alarms = alarmService.findAlarms(tenantId, AlarmQuery.builder()
.affectedEntityId(parentId)
.status(AlarmStatus.ACTIVE_UNACK).pageLink(
new TimePageLink(1, 0L, System.currentTimeMillis(), false)
).build()).get();
Assert.assertNotNull(alarms.getData());
Assert.assertEquals(0, alarms.getData().size());
toAlarmRelations = relationService.findByTo(tenantId, created.getId(), RelationTypeGroup.ALARM);
Assert.assertEquals(0, toAlarmRelations.size());
fromChildRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
Assert.assertEquals(0, fromChildRelations.size());
fromParentRelations = relationService.findByFrom(tenantId, childId, RelationTypeGroup.ALARM);
Assert.assertEquals(0, fromParentRelations.size());
}
}

12
pom.xml

@ -84,6 +84,7 @@
<delight-nashorn-sandbox.version>0.1.14</delight-nashorn-sandbox.version>
<kafka.version>2.0.0</kafka.version>
<bucket4j.version>4.1.1</bucket4j.version>
<fst.version>2.57</fst.version>
</properties>
<modules>
@ -756,12 +757,6 @@
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
</dependency>
<dependency>
<groupId>ru.yandex.qatools.embed</groupId>
<artifactId>postgresql-embedded</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
@ -795,6 +790,11 @@
<artifactId>bucket4j-core</artifactId>
<version>${bucket4j.version}</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>${fst.version}</version>
</dependency>
<dependency>
<groupId>io.springfox.ui</groupId>
<artifactId>springfox-swagger-ui-rfc6570</artifactId>

38
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbAbstractRelationActionNode.java

@ -61,10 +61,8 @@ import static org.thingsboard.rule.engine.api.util.DonAsynchron.withCallback;
public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationActionNodeConfiguration> implements TbNode {
protected C config;
protected EntityId fromId;
protected EntityId toId;
private LoadingCache<Entitykey, EntityContainer> entityIdCache;
private LoadingCache<EntityKey, EntityContainer> entityIdCache;
@Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
@ -99,29 +97,33 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
protected ListenableFuture<EntityContainer> getEntity(TbContext ctx, TbMsg msg) {
String entityName = TbNodeUtils.processPattern(this.config.getEntityNamePattern(), msg.getMetaData());
String type = null;
String type;
if (this.config.getEntityTypePattern() != null) {
type = TbNodeUtils.processPattern(this.config.getEntityTypePattern(), msg.getMetaData());
} else {
type = null;
}
EntityType entityType = EntityType.valueOf(this.config.getEntityType());
Entitykey key = new Entitykey(entityName, type, entityType);
EntityKey key = new EntityKey(entityName, type, entityType);
return ctx.getDbCallbackExecutor().executeAsync(() -> {
EntityContainer entityContainer = entityIdCache.get(key);
if (entityContainer.getEntityId() == null) {
throw new RuntimeException("No entity found with type '" + key.getEntityType() + " ' and name '" + key.getEntityName() + "'.");
throw new RuntimeException("No entity found with type '" + key.getEntityType() + "' and name '" + key.getEntityName() + "'.");
}
return entityContainer;
});
}
protected void processSingleSearchDirection(TbMsg msg, EntityContainer entityContainer) {
protected SearchDirectionIds processSingleSearchDirection(TbMsg msg, EntityContainer entityContainer) {
SearchDirectionIds searchDirectionIds = new SearchDirectionIds();
if (EntitySearchDirection.FROM.name().equals(config.getDirection())) {
fromId = EntityIdFactory.getByTypeAndId(entityContainer.getEntityType().name(), entityContainer.getEntityId().toString());
toId = msg.getOriginator();
searchDirectionIds.setFromId(EntityIdFactory.getByTypeAndId(entityContainer.getEntityType().name(), entityContainer.getEntityId().toString()));
searchDirectionIds.setToId(msg.getOriginator());
} else {
toId = EntityIdFactory.getByTypeAndId(entityContainer.getEntityType().name(), entityContainer.getEntityId().toString());
fromId = msg.getOriginator();
searchDirectionIds.setToId(EntityIdFactory.getByTypeAndId(entityContainer.getEntityType().name(), entityContainer.getEntityId().toString()));
searchDirectionIds.setFromId(msg.getOriginator());
}
return searchDirectionIds;
}
protected ListenableFuture<List<EntityRelation>> processListSearchDirection(TbContext ctx, TbMsg msg) {
@ -134,13 +136,19 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
@Data
@AllArgsConstructor
private static class Entitykey {
private static class EntityKey {
private String entityName;
private String type;
private EntityType entityType;
}
private static class EntityCacheLoader extends CacheLoader<Entitykey, EntityContainer> {
@Data
protected static class SearchDirectionIds {
private EntityId fromId;
private EntityId toId;
}
private static class EntityCacheLoader extends CacheLoader<EntityKey, EntityContainer> {
private final TbContext ctx;
private final boolean createIfNotExists;
@ -151,11 +159,11 @@ public abstract class TbAbstractRelationActionNode<C extends TbAbstractRelationA
}
@Override
public EntityContainer load(Entitykey key) {
public EntityContainer load(EntityKey key) {
return loadEntity(key);
}
private EntityContainer loadEntity(Entitykey entitykey) {
private EntityContainer loadEntity(EntityKey entitykey) {
EntityType type = entitykey.getEntityType();
EntityContainer targetEntity = new EntityContainer();
targetEntity.setEntityType(type);

3
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java

@ -54,7 +54,8 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig
@Override
protected ListenableFuture<AlarmResult> processAlarm(TbContext ctx, TbMsg msg) {
ListenableFuture<Alarm> latest = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), config.getAlarmType());
String alarmType = TbNodeUtils.processPattern(this.config.getAlarmType(), msg.getMetaData());
ListenableFuture<Alarm> latest = ctx.getAlarmService().findLatestByOriginatorAndType(ctx.getTenantId(), msg.getOriginator(), alarmType);
return Futures.transformAsync(latest, a -> {
if (a != null && !a.getStatus().isCleared()) {
return clearAlarm(ctx, msg, a);

45
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCreateRelationNode.java

@ -65,92 +65,91 @@ public class TbCreateRelationNode extends TbAbstractRelationActionNode<TbCreateR
}
private ListenableFuture<Boolean> createIfAbsent(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
processSingleSearchDirection(msg, entityContainer);
return Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON),
SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer);
return Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON),
result -> {
if (!result) {
return processCreateRelation(ctx, entityContainer);
return processCreateRelation(ctx, entityContainer, sdId);
}
return Futures.immediateFuture(true);
});
}
private ListenableFuture<Boolean> processCreateRelation(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processCreateRelation(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
switch (entityContainer.getEntityType()) {
case ASSET:
return processAsset(ctx, entityContainer);
return processAsset(ctx, entityContainer, sdId);
case DEVICE:
return processDevice(ctx, entityContainer);
return processDevice(ctx, entityContainer, sdId);
case CUSTOMER:
return processCustomer(ctx, entityContainer);
return processCustomer(ctx, entityContainer, sdId);
case DASHBOARD:
return processDashboard(ctx, entityContainer);
return processDashboard(ctx, entityContainer, sdId);
case ENTITY_VIEW:
return processView(ctx, entityContainer);
return processView(ctx, entityContainer, sdId);
case TENANT:
return processTenant(ctx, entityContainer);
return processTenant(ctx, entityContainer, sdId);
}
return Futures.immediateFuture(true);
}
private ListenableFuture<Boolean> processView(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processView(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getEntityViewService().findEntityViewByIdAsync(ctx.getTenantId(), new EntityViewId(entityContainer.getEntityId().getId())), entityView -> {
if (entityView != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
private ListenableFuture<Boolean> processDevice(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processDevice(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), new DeviceId(entityContainer.getEntityId().getId())), device -> {
if (device != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
private ListenableFuture<Boolean> processAsset(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processAsset(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), new AssetId(entityContainer.getEntityId().getId())), asset -> {
if (asset != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
private ListenableFuture<Boolean> processCustomer(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processCustomer(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), new CustomerId(entityContainer.getEntityId().getId())), customer -> {
if (customer != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
private ListenableFuture<Boolean> processDashboard(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processDashboard(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getDashboardService().findDashboardByIdAsync(ctx.getTenantId(), new DashboardId(entityContainer.getEntityId().getId())), dashboard -> {
if (dashboard != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
private ListenableFuture<Boolean> processTenant(TbContext ctx, EntityContainer entityContainer) {
private ListenableFuture<Boolean> processTenant(TbContext ctx, EntityContainer entityContainer, SearchDirectionIds sdId) {
return Futures.transformAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), new TenantId(entityContainer.getEntityId().getId())), tenant -> {
if (tenant != null) {
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON));
return ctx.getRelationService().saveRelationAsync(ctx.getTenantId(), new EntityRelation(sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON));
} else {
return Futures.immediateFuture(true);
}
});
}
}

11
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbDeleteRelationNode.java

@ -93,18 +93,19 @@ public class TbDeleteRelationNode extends TbAbstractRelationActionNode<TbDeleteR
}
private ListenableFuture<Boolean> processSingle(TbContext ctx, TbMsg msg, EntityContainer entityContainer) {
processSingleSearchDirection(msg, entityContainer);
return Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON),
SearchDirectionIds sdId = processSingleSearchDirection(msg, entityContainer);
return Futures.transformAsync(ctx.getRelationService().checkRelation(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON),
result -> {
if (result) {
return processSingleDeleteRelation(ctx);
return processSingleDeleteRelation(ctx, sdId);
}
return Futures.immediateFuture(true);
});
}
private ListenableFuture<Boolean> processSingleDeleteRelation(TbContext ctx) {
return ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), fromId, toId, config.getRelationType(), RelationTypeGroup.COMMON);
private ListenableFuture<Boolean> processSingleDeleteRelation(TbContext ctx, SearchDirectionIds sdId) {
return ctx.getRelationService().deleteRelationAsync(ctx.getTenantId(), sdId.getFromId(), sdId.getToId(), config.getRelationType(), RelationTypeGroup.COMMON);
}
}

1
ui/src/app/entity/entity-subtype-autocomplete.directive.js

@ -62,6 +62,7 @@ export default function EntitySubtypeAutocomplete($compile, $templateCache, $q,
}
scope.subTypeSearchTextChanged = function() {
scope.subType = scope.subTypeSearchText;
}
scope.updateView = function () {

2
ui/src/app/entity/entity-subtype-autocomplete.tpl.html

@ -28,7 +28,7 @@
md-min-length="0"
placeholder="{{ selectEntitySubtypeText | translate }}"
md-floating-label="{{ entitySubtypeText | translate }}"
md-select-on-match="true"
md-select-on-match="false"
md-menu-class="tb-entity-subtype-autocomplete">
<md-item-template>
<div class="tb-entity-subtype-item">

1581
ui/src/app/locale/locale.constant-de_DE.json

File diff suppressed because it is too large

7
ui/src/app/locale/locale.constant-en_US.json

@ -1034,7 +1034,6 @@
"modbus-register-count": "Register count",
"modbus-register-count-range": "Register count should be a positive value.",
"modbus-byte-order": "Byte order",
"sync": {
"status": "Status",
"sync": "Sync",
@ -1042,7 +1041,6 @@
"last-sync-time": "Last sync time",
"not-available": "Not available"
},
"export-extensions-configuration": "Export extensions configuration",
"import-extensions-configuration": "Import extensions configuration",
"import-extensions": "Import extensions",
@ -1568,7 +1566,8 @@
"language": {
"language": "Language",
"locales": {
"fr_FR": "French",
"de_DE": "German",
"fr_FR": "French",
"zh_CN": "Chinese",
"en_US": "English",
"it_IT": "Italian",
@ -1579,4 +1578,4 @@
"tr_TR": "Turkish"
}
}
}
}

5
ui/src/app/locale/locale.constant-es_ES.json

@ -1034,7 +1034,6 @@
"modbus-register-count": "Contador del registro",
"modbus-register-count-range": "Contador del registro debe ser un valor positivo.",
"modbus-byte-order": "Orden del byte",
"sync": {
"status": "Estado",
"sync": "Sincronización",
@ -1042,7 +1041,6 @@
"last-sync-time": "Último tiempo de sincroniación",
"not-available": "No disponible"
},
"export-extensions-configuration": "Exportar configuración de extensiones",
"import-extensions-configuration": "Importar configuración de extensiones",
"import-extensions": "Importar extensiones",
@ -1568,6 +1566,7 @@
"language": {
"language": "Lenguaje",
"locales": {
"de_DE": "Alemán",
"fr_FR": "Francés",
"zh_CN": "Chino",
"en_US": "Inglés",
@ -1579,4 +1578,4 @@
"tr_TR": "Turco"
}
}
}
}

3
ui/src/app/locale/locale.constant-fr_FR.json

@ -1003,6 +1003,7 @@
"language": {
"language": "Language",
"locales": {
"de_DE": "Allemand",
"en_US": "Anglais",
"fr_FR": "Français",
"es_ES": "Espagnol",
@ -1459,4 +1460,4 @@
"widgets-bundle-required": "Un groupe de widgets est requis.",
"widgets-bundles": "Groupes de widgets"
}
}
}

21
ui/src/app/locale/locale.constant-it_IT.json

@ -100,7 +100,7 @@
"UNACK": "Non riconosciuto"
},
"display-status": {
"ACTIVE_UNACK": "Active Unacknowledged",
"ACTIVE_UNACK": "Active Unacknowledged",
"ACTIVE_ACK": "Active Acknowledged",
"CLEARED_UNACK": "Cleared Unacknowledged",
"CLEARED_ACK": "Cleared Acknowledged"
@ -109,8 +109,8 @@
"created-time": "Orario di creazione",
"type": "Tipo",
"severity": "Livello di gravità",
"originator": "Origine",
"originator-type": "Tipo origine",
"originator": "Origine",
"originator-type": "Tipo origine",
"details": "Dettagli",
"status": "Stato",
"alarm-details": "Dettagli allarme",
@ -132,9 +132,9 @@
"polling-interval-required": "Intervallo di polling Allarmi richiesto.",
"min-polling-interval-message": "L'intervallo di polling deve essere di almeno 1 sec.",
"aknowledge-alarms-title": "Conferma { count, plural, 1 {1 allarme} other {# allarmi} }",
"aknowledge-alarms-text": "Sei sicuro di voler confermare { count, plural, 1 {1 allarme} other {# allarmi} }?",
"aknowledge-alarms-text": "Sei sicuro di voler confermare { count, plural, 1 {1 allarme} other {# allarmi} }?",
"clear-alarms-title": "Elimina { count, plural, 1 {1 allarme} other {# allarmi} }",
"clear-alarms-text": "Sei sicuro di voler eliminare { count, plural, 1 {1 allarme} other {# allarmi} }?"
"clear-alarms-text": "Sei sicuro di voler eliminare { count, plural, 1 {1 allarme} other {# allarmi} }?"
},
"alias": {
"add": "Aggiungi alias",
@ -910,7 +910,6 @@
"modbus-register-count": "Register count",
"modbus-register-count-range": "Register count should be a positive value.",
"modbus-byte-order": "Byte order",
"sync": {
"status": "Stato",
"sync": "Sincronizzato",
@ -918,7 +917,6 @@
"last-sync-time": "Ultima sincronizzazione",
"not-available": "Non disponibile"
},
"export-extensions-configuration": "Esporta configurazione estensioni",
"import-extensions-configuration": "Importa configurazione estensioni",
"import-extensions": "Importa estensione",
@ -1414,7 +1412,7 @@
"export": "Esporta un tipo di widget",
"export-failed-error": "Impossibile esportare il tipo di widget: {{error}}",
"create-new-widget-type": "Crea un nuovo tipo di widget",
"widget-type-file": "Widget type file",
"widget-type-file": "Widget type file",
"invalid-widget-type-file-error": "Impossibile importare un tipo di widget: struttura dati del widget non valida."
},
"icon": {
@ -1424,7 +1422,7 @@
"show-all": "Mostra tutte le icone"
},
"custom": {
"widget-action": {
"widget-action": {
"action-cell-button": "Action cell button",
"row-click": "On row click",
"marker-click": "On marker click",
@ -1434,7 +1432,8 @@
"language": {
"language": "Lingua",
"locales": {
"fr_FR": "Francese",
"de_DE": "Tedesco",
"fr_FR": "Francese",
"zh_CN": "Cinese",
"ko_KR": "Coreano",
"en_US": "Inglese",
@ -1445,4 +1444,4 @@
"tr_TR": "Turco"
}
}
}
}

21
ui/src/app/locale/locale.constant-ja_JA.json

@ -288,11 +288,11 @@
"type-suspended": "一時停止中",
"type-credentials-read": "信用証明書を読む",
"type-attributes-read": "読み取られた属性",
"type-relation-add-or-update": "関係が更新されました",
"type-relation-delete": "関係が削除されました",
"type-relations-delete": "すべてのリレーションを削除",
"type-alarm-ack": "承認された",
"type-alarm-clear": "クリアされた",
"type-relation-add-or-update": "関係が更新されました",
"type-relation-delete": "関係が削除されました",
"type-relations-delete": "すべてのリレーションを削除",
"type-alarm-ack": "承認された",
"type-alarm-clear": "クリアされた",
"status-success": "成功",
"status-failure": "失敗",
"audit-log-details": "監査ログの詳細",
@ -322,7 +322,7 @@
"common": {
"username": "ユーザー名",
"password": "パスワード",
"enter-username": "ユーザーネームを入力してください",
"enter-username": "ユーザーネームを入力してください",
"enter-password": "パスワードを入力する",
"enter-search": "検索を入力"
},
@ -919,7 +919,6 @@
"modbus-register-count": "レジスタ数",
"modbus-register-count-range": "レジスタ数は正の値でなければなりません。",
"modbus-byte-order": "バイト順",
"sync": {
"status": "状態",
"sync": "同期",
@ -927,7 +926,6 @@
"last-sync-time": "前回の同期時間",
"not-available": "利用不可"
},
"export-extensions-configuration": "エクステンション設定のエクスポート",
"import-extensions-configuration": "エクステンション設定のインポート",
"import-extensions": "拡張機能のインポート",
@ -1417,7 +1415,7 @@
"action-source-required": "アクションソースが必要です。",
"action-name": "名",
"action-name-required": "アクション名は必須です。",
"action-name-not-unique": "同じ名前の別のアクションがすでに存在します。<br/>アクション名は、同じアクションソース内で一意である必要があります。",
"action-name-not-unique": "同じ名前の別のアクションがすでに存在します。<br/>アクション名は、同じアクションソース内で一意である必要があります。",
"action-icon": "アイコン",
"action-type": "タイプ",
"action-type-required": "アクションタイプが必要です。",
@ -1427,7 +1425,7 @@
"delete-action-text": "'{{actionName}}'?"
},
"widget-type": {
"import": "インポートウィジェットタイプ",
"import": "インポートウィジェットタイプ",
"export": "ウィジェットのタイプをエクスポートする",
"export-failed-error": "{{error}}",
"create-new-widget-type": "新しいウィジェットタイプを作成する",
@ -1451,6 +1449,7 @@
"language": {
"language": "言語",
"locales": {
"de_DE": "ドイツ語",
"en_US": "英語",
"ko_KR": "韓国語",
"it_IT": "イタリアの",
@ -1461,4 +1460,4 @@
"tr_TR": "トルコ語"
}
}
}
}

8
ui/src/app/locale/locale.constant-ko_KR.json

@ -85,7 +85,6 @@
"enable-tls": "TLS 사용",
"send-test-mail": "테스트 메일 보내기"
},
"alarm": {
"alarm": "Alarm",
"alarms": "Alarms",
@ -831,7 +830,6 @@
"modbus-register-count": "Register count",
"modbus-register-count-range": "Register count should be a positive value.",
"modbus-byte-order": "Byte order",
"sync": {
"status": "Status",
"sync": "Sync",
@ -839,7 +837,6 @@
"last-sync-time": "Last sync time",
"not-available": "Not available"
},
"export-extensions-configuration": "Export extensions configuration",
"import-extensions-configuration": "Import extensions configuration",
"import-extensions": "Import extensions",
@ -1328,8 +1325,9 @@
"language": {
"language": "언어",
"locales": {
"de_DE": "독일어",
"en_US": "영어",
"fr_FR": "프랑스의",
"fr_FR": "프랑스의",
"ko_KR": "한글",
"zh_CN": "중국어",
"ru_RU": "러시아어",
@ -1339,4 +1337,4 @@
"tr_TR": "터키어"
}
}
}
}

5
ui/src/app/locale/locale.constant-ru_RU.json

@ -1032,7 +1032,6 @@
"modbus-register-count": "Количество регистров",
"modbus-register-count-range": "Количество регистров должно быть больше ноля.",
"modbus-byte-order": "Порядок байтов",
"sync": {
"status": "Статус",
"sync": "Синхронизирован",
@ -1040,7 +1039,6 @@
"last-sync-time": "Время последней синхронизации",
"not-available": "Не доступен"
},
"export-extensions-configuration": "Экспортировать конфигурацию расширений",
"import-extensions-configuration": "Импортировать конфигурацию расширений",
"import-extensions": "Импортировать расширения",
@ -1566,6 +1564,7 @@
"language": {
"language": "Язык",
"locales": {
"de_DE": "Немецкий",
"en_US": "Английский",
"zh_CN": "Китайский",
"ko_KR": "Корейский",
@ -1577,4 +1576,4 @@
"ja_JA": "Японский"
}
}
}
}

3
ui/src/app/locale/locale.constant-tr_TR.json

@ -1175,7 +1175,7 @@
"delete-rulechains-action-title": "{ count, plural, 1 {1 kuralı} other {# kuralı} } sil",
"delete-rulechains-text": "UYARI: Onaylandıktan sonra seçili tüm kurallar ve ilişkili tüm veriler geri yüklenemez şekilde silinecektir.",
"add-rulechain-text": "Yeni kural ekle",
"no-rulechains-text":"Hiçbir kural bulunamadı",
"no-rulechains-text": "Hiçbir kural bulunamadı",
"rulechain-details": "Kural detayları",
"details": "Detaylar",
"events": "Olaylar",
@ -1531,6 +1531,7 @@
"language": {
"language": "Dil",
"locales": {
"de_DE": "Almanca",
"fr_FR": "Fransızca",
"zh_CN": "Çince",
"en_US": "İngilizce",

7
ui/src/app/locale/locale.constant-zh_CN.json

@ -916,7 +916,6 @@
"last-sync-time": "最后同步时间",
"not-available": "无法使用"
},
"export-extensions-configuration": "导出扩展配置",
"import-extensions-configuration": "导入扩展配置",
"import-extensions": "导入扩展",
@ -1299,7 +1298,6 @@
"saveAs": "部件另存为",
"save-widget-type-as": "部件类型另存为",
"save-widget-type-as-text": "请输入新的部件标题或选择目标部件包",
"toggle-fullscreen": "切换全屏",
"run": "运行部件",
"title": "部件标题",
@ -1437,8 +1435,9 @@
"language": {
"language": "语言",
"locales": {
"de_DE": "德语",
"en_US": "英语",
"fr_FR": "法国",
"fr_FR": "法国",
"ko_KR": "韩语",
"zh_CN": "汉语",
"ru_RU": "俄语",
@ -1448,4 +1447,4 @@
"tr_TR": "土耳其"
}
}
}
}

42
ui/src/app/widget/lib/google-map.js

@ -314,6 +314,48 @@ export default class TbGoogleMap {
polyline.setMap(null);
}
createPolygon(latLangs, settings) {
let polygon = new google.maps.Polygon({
map: this.map,
paths: latLangs,
strokeColor: settings.polygonStrokeColor,
strokeOpacity: settings.polygonStrokeColor,
fillColor: settings.polygonColor,
fillOpacity: settings.polygonOpacity,
strokeWeight: settings.polygonStrokeWeight
});
return polygon;
}
/* eslint-disable no-undef */
removePolygon (polygon) {
polygon.setMap(null);
}
/* eslint-disable no-undef,no-unused-vars */
updatePolygonColor (polygon, settings, color) {
let options = {
paths: polygon.getPaths(),
map: this.map,
strokeColor: color,
fillColor: color,
strokeWeight: settings.polygonStrokeWeight
}
}
/* eslint-disable no-undef ,no-unused-vars*/
getPolygonLatLngs(polygon) {
return polygon.getPaths().getArray();
}
setPolygonLatLngs(polygon, latLngs) {
polygon.setPaths(latLngs);
}
/* eslint-disable no-undef */
fitBounds(bounds) {
if (this.dontFitMapBounds && this.defaultZoomLevel) {

15
ui/src/app/widget/lib/image-map.js

@ -369,6 +369,21 @@ export default class TbImageMap {
removePolyline(/*polyline*/) {
}
createPolygon(/*latLangs, settings*/) {
}
removePolygon(/*latLangs, settings*/) {
}
updatePolygonColor(/*latLangs, settings*/) {
}
getPolygonLatLngs(/*latLangs, settings*/) {
}
setPolygonLatLngs(/*latLangs, settings*/) {
}
fitBounds() {
}

2251
ui/src/app/widget/lib/map-widget2.js

File diff suppressed because it is too large

494
ui/src/app/widget/lib/openstreet-map.js

@ -19,234 +19,270 @@ import 'leaflet-providers';
export default class TbOpenStreetMap {
constructor($containerElement, utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, mapProvider) {
this.utils = utils;
this.defaultZoomLevel = defaultZoomLevel;
this.dontFitMapBounds = dontFitMapBounds;
this.minZoomLevel = minZoomLevel;
this.tooltips = [];
if (!mapProvider) {
mapProvider = "OpenStreetMap.Mapnik";
}
this.map = L.map($containerElement[0]).setView([0, 0], this.defaultZoomLevel || 8);
var tileLayer = L.tileLayer.provider(mapProvider);
tileLayer.addTo(this.map);
if (initCallback) {
setTimeout(initCallback, 0); //eslint-disable-line
}
}
inited() {
return angular.isDefined(this.map);
}
updateMarkerLabel(marker, settings) {
marker.unbindTooltip();
marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
{ className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
}
updateMarkerColor(marker, color) {
this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
marker.setIcon(iconInfo.icon);
});
}
updateMarkerIcon(marker, settings) {
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (settings.showLabel) {
marker.unbindTooltip();
marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
{ className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
}
});
}
createMarkerIcon(marker, settings, onMarkerIconReady) {
var currentImage = settings.currentImage;
var opMap = this;
if (currentImage && currentImage.url) {
this.utils.loadImageAspect(currentImage.url).then(
(aspect) => {
if (aspect) {
var width;
var height;
if (aspect > 1) {
width = currentImage.size;
height = currentImage.size / aspect;
} else {
width = currentImage.size * aspect;
height = currentImage.size;
}
var icon = L.icon({
iconUrl: currentImage.url,
iconSize: [width, height],
iconAnchor: [width/2, height],
popupAnchor: [0, -height]
});
var iconInfo = {
size: [width, height],
icon: icon
};
onMarkerIconReady(iconInfo);
} else {
opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
);
} else {
this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
var pinColor = color.substr(1);
var icon = L.icon({
iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
iconSize: [21, 34],
iconAnchor: [10, 34],
popupAnchor: [0, -34],
shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
shadowSize: [40, 37],
shadowAnchor: [12, 35]
});
var iconInfo = {
size: [21, 34],
icon: icon
};
onMarkerIconReady(iconInfo);
}
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
var marker = L.marker(location, {});
var opMap = this;
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (settings.showLabel) {
marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
marker.bindTooltip('<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
{ className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset });
}
marker.addTo(opMap.map);
});
if (settings.displayTooltip) {
this.createTooltip(marker, dsIndex, settings, markerArgs);
}
if (onClickListener) {
marker.on('click', onClickListener);
}
return marker;
}
removeMarker(marker) {
this.map.removeLayer(marker);
}
createTooltip(marker, dsIndex, settings, markerArgs) {
var popup = L.popup();
popup.setContent('');
marker.bindPopup(popup, {autoClose: settings.autocloseTooltip, closeOnClick: false});
this.tooltips.push( {
markerArgs: markerArgs,
popup: popup,
locationSettings: settings,
dsIndex: dsIndex
});
}
updatePolylineColor(polyline, settings, color) {
var style = {
color: color,
opacity: settings.strokeOpacity,
weight: settings.strokeWeight
};
polyline.setStyle(style);
}
createPolyline(locations, settings) {
var polyline = L.polyline(locations,
{
color: settings.color,
opacity: settings.strokeOpacity,
weight: settings.strokeWeight
}
).addTo(this.map);
return polyline;
}
removePolyline(polyline) {
this.map.removeLayer(polyline);
}
fitBounds(bounds) {
if (bounds.isValid()) {
if (this.dontFitMapBounds && this.defaultZoomLevel) {
this.map.setZoom(this.defaultZoomLevel, {animate: false});
this.map.panTo(bounds.getCenter(), {animate: false});
} else {
var tbMap = this;
this.map.once('zoomend', function() {
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
tbMap.map.setZoom(tbMap.minZoomLevel, {animate: false});
}
});
this.map.fitBounds(bounds, {padding: [50, 50], animate: false});
}
}
}
createLatLng(lat, lng) {
return L.latLng(lat, lng);
}
extendBoundsWithMarker(bounds, marker) {
bounds.extend(marker.getLatLng());
}
getMarkerPosition(marker) {
return marker.getLatLng();
}
setMarkerPosition(marker, latLng) {
marker.setLatLng(latLng);
}
getPolylineLatLngs(polyline) {
return polyline.getLatLngs();
}
setPolylineLatLngs(polyline, latLngs) {
polyline.setLatLngs(latLngs);
}
createBounds() {
return L.latLngBounds();
}
extendBounds(bounds, polyline) {
if (polyline && polyline.getLatLngs()) {
bounds.extend(polyline.getBounds());
}
}
invalidateSize() {
this.map.invalidateSize(true);
}
getTooltips() {
return this.tooltips;
}
constructor($containerElement, utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, mapProvider) {
this.utils = utils;
this.defaultZoomLevel = defaultZoomLevel;
this.dontFitMapBounds = dontFitMapBounds;
this.minZoomLevel = minZoomLevel;
this.tooltips = [];
if (!mapProvider) {
mapProvider = "OpenStreetMap.Mapnik";
}
this.map = L.map($containerElement[0]).setView([0, 0], this.defaultZoomLevel || 8);
var tileLayer = L.tileLayer.provider(mapProvider);
tileLayer.addTo(this.map);
if (initCallback) {
setTimeout(initCallback, 0); //eslint-disable-line
}
}
inited() {
return angular.isDefined(this.map);
}
updateMarkerLabel(marker, settings) {
marker.unbindTooltip();
marker.bindTooltip('<div style="color: ' + settings.labelColor + ';"><b>' + settings.labelText + '</b></div>',
{className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset});
}
updateMarkerColor(marker, color) {
this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
marker.setIcon(iconInfo.icon);
});
}
updateMarkerIcon(marker, settings) {
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (settings.showLabel) {
marker.unbindTooltip();
marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
marker.bindTooltip('<div style="color: ' + settings.labelColor + ';"><b>' + settings.labelText + '</b></div>',
{className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset});
}
});
}
createMarkerIcon(marker, settings, onMarkerIconReady) {
var currentImage = settings.currentImage;
var opMap = this;
if (currentImage && currentImage.url) {
this.utils.loadImageAspect(currentImage.url).then(
(aspect) => {
if (aspect) {
var width;
var height;
if (aspect > 1) {
width = currentImage.size;
height = currentImage.size / aspect;
} else {
width = currentImage.size * aspect;
height = currentImage.size;
}
var icon = L.icon({
iconUrl: currentImage.url,
iconSize: [width, height],
iconAnchor: [width / 2, height],
popupAnchor: [0, -height]
});
var iconInfo = {
size: [width, height],
icon: icon
};
onMarkerIconReady(iconInfo);
} else {
opMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
);
} else {
this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
var pinColor = color.substr(1);
var icon = L.icon({
iconUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=%E2%80%A2|' + pinColor,
iconSize: [21, 34],
iconAnchor: [10, 34],
popupAnchor: [0, -34],
shadowUrl: 'https://chart.apis.google.com/chart?chst=d_map_pin_shadow',
shadowSize: [40, 37],
shadowAnchor: [12, 35]
});
var iconInfo = {
size: [21, 34],
icon: icon
};
onMarkerIconReady(iconInfo);
}
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
var marker = L.marker(location, {});
var opMap = this;
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (settings.showLabel) {
marker.tooltipOffset = [0, -iconInfo.size[1] + 10];
marker.bindTooltip('<div style="color: ' + settings.labelColor + ';"><b>' + settings.labelText + '</b></div>',
{className: 'tb-marker-label', permanent: true, direction: 'top', offset: marker.tooltipOffset});
}
marker.addTo(opMap.map);
});
if (settings.displayTooltip) {
this.createTooltip(marker, dsIndex, settings, markerArgs);
}
if (onClickListener) {
marker.on('click', onClickListener);
}
return marker;
}
removeMarker(marker) {
this.map.removeLayer(marker);
}
createTooltip(marker, dsIndex, settings, markerArgs) {
var popup = L.popup();
popup.setContent('');
marker.bindPopup(popup, {autoClose: settings.autocloseTooltip, closeOnClick: false});
this.tooltips.push({
markerArgs: markerArgs,
popup: popup,
locationSettings: settings,
dsIndex: dsIndex
});
}
updatePolylineColor(polyline, settings, color) {
var style = {
color: color,
opacity: settings.strokeOpacity,
weight: settings.strokeWeight
};
polyline.setStyle(style);
}
createPolyline(locations, settings) {
var polyline = L.polyline(locations,
{
color: settings.color,
opacity: settings.strokeOpacity,
weight: settings.strokeWeight
}
).addTo(this.map);
return polyline;
}
removePolyline(polyline) {
this.map.removeLayer(polyline);
}
createPolygon(latLangs, settings) {
let polygon = L.polygon(latLangs, {
fill: true,
fillColor: settings.polygonColor,
color: settings.polygonStrokeColor,
weight: settings.polygonStrokeWeight,
fillOpacity: settings.polygonOpacity,
opacity: settings.polygonStrokeOpacity
}).addTo(this.map);
return polygon;
}
removePolygon(polygon) {
this.map.removeLayer(polygon);
}
updatePolygonColor(polygon, settings, color) {
let style = {
fill: true,
fillColor: color,
color: color,
weight: settings.polygonStrokeWeight,
fillOpacity: settings.polygonOpacity,
opacity: settings.polygonStrokeOpacity
};
polygon.setStyle(style);
}
getPolygonLatLngs(polygon) {
return polygon.getLatLngs();
}
setPolygonLatLngs(polygon, latLngs) {
polygon.setLatLngs(latLngs);
}
fitBounds(bounds) {
if (bounds.isValid()) {
if (this.dontFitMapBounds && this.defaultZoomLevel) {
this.map.setZoom(this.defaultZoomLevel, {animate: false});
this.map.panTo(bounds.getCenter(), {animate: false});
} else {
var tbMap = this;
this.map.once('zoomend', function () {
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
tbMap.map.setZoom(tbMap.minZoomLevel, {animate: false});
}
});
this.map.fitBounds(bounds, {padding: [50, 50], animate: false});
}
}
}
createLatLng(lat, lng) {
return L.latLng(lat, lng);
}
extendBoundsWithMarker(bounds, marker) {
bounds.extend(marker.getLatLng());
}
getMarkerPosition(marker) {
return marker.getLatLng();
}
setMarkerPosition(marker, latLng) {
marker.setLatLng(latLng);
}
getPolylineLatLngs(polyline) {
return polyline.getLatLngs();
}
setPolylineLatLngs(polyline, latLngs) {
polyline.setLatLngs(latLngs);
}
createBounds() {
return L.latLngBounds();
}
extendBounds(bounds, polyline) {
if (polyline && polyline.getLatLngs()) {
bounds.extend(polyline.getBounds());
}
}
invalidateSize() {
this.map.invalidateSize(true);
}
getTooltips() {
return this.tooltips;
}
}

786
ui/src/app/widget/lib/tencent-map.js

@ -14,377 +14,425 @@
* limitations under the License.
*/
var tmGlobals = {
loadingTmId: null,
tmApiKeys: {}
loadingTmId: null,
tmApiKeys: {}
}
export default class TbTencentMap {
constructor($containerElement,utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, tmApiKey, tmDefaultMapType) {
var tbMap = this;
this.utils = utils;
this.defaultZoomLevel = defaultZoomLevel;
this.dontFitMapBounds = dontFitMapBounds;
this.minZoomLevel = minZoomLevel;
this.tooltips = [];
this.defaultMapType = tmDefaultMapType;
function clearGlobalId() {
if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
tmGlobals.loadingTmId = null;
}
}
function displayError(message) {
$containerElement.html( // eslint-disable-line angular/angularelement
"<div class='error'>"+ message + "</div>"
);
}
function initTencentMap() {
tbMap.map = new qq.maps.Map($containerElement[0], { // eslint-disable-line no-undef
scrollwheel: true,
mapTypeId: getTencentMapTypeId(tbMap.defaultMapType),
zoom: tbMap.defaultZoomLevel || 8
});
if (initCallback) {
initCallback();
}
}
/* eslint-disable no-undef */
function getTencentMapTypeId(mapType) {
var mapTypeId =qq.maps.MapTypeId.ROADMAP;
if (mapType) {
if (mapType === 'hybrid') {
mapTypeId = qq.maps.MapTypeId.HYBRID;
} else if (mapType === 'satellite') {
mapTypeId = qq.maps.MapTypeId.SATELLITE;
} else if (mapType === 'terrain') {
mapTypeId = qq.maps.MapTypeId.ROADMAP;
}
}
return mapTypeId;
}
/* eslint-enable no-undef */
this.mapId = '' + Math.random().toString(36).substr(2, 9);
this.apiKey = tmApiKey || '84d6d83e0e51e481e50454ccbe8986b';
window.tm_authFailure = function() { // eslint-disable-line no-undef, angular/window-service
if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
tmGlobals.loadingTmId = null;
tmGlobals.tmApiKeys[tbMap.apiKey].error = 'Unable to authentificate for tencent Map API.</br>Please check your API key.';
displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
}
};
this.initMapFunctionName = 'initTencentMap_' + this.mapId;
window[this.initMapFunctionName] = function() { // eslint-disable-line no-undef, angular/window-service
tmGlobals.tmApiKeys[tbMap.apiKey].loaded = true;
initTencentMap();
for (var p = 0; p < tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits.length; p++) {
var pendingInit = tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits[p];
pendingInit();
}
tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits = [];
};
if (this.apiKey && this.apiKey.length > 0) {
if (tmGlobals.tmApiKeys[this.apiKey]) {
if (tmGlobals.tmApiKeys[this.apiKey].error) {
displayError(tmGlobals.tmApiKeys[this.apiKey].error);
} else if (tmGlobals.tmApiKeys[this.apiKey].loaded) {
initTencentMap();
} else {
tmGlobals.tmApiKeys[this.apiKey].pendingInits.push(initTencentMap);
}
} else {
tmGlobals.tmApiKeys[this.apiKey] = {
loaded: false,
pendingInits: []
};
var tencentMapScriptRes = 'https://map.qq.com/api/js?v=2.exp&key='+this.apiKey+'&callback='+this.initMapFunctionName;
tmGlobals.loadingTmId = this.mapId;
lazyLoad.load({ type: 'js', path: tencentMapScriptRes }).then( // eslint-disable-line no-undef
function success() {
setTimeout(clearGlobalId, 2000); // eslint-disable-line no-undef, angular/timeout-service
},
function fail(e) {
clearGlobalId();
tmGlobals.tmApiKeys[tbMap.apiKey].error = 'tencent map api load failed!</br>'+e;
displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
}
);
}
} else {
displayError('No tencent Map Api Key provided!');
}
}
inited() {
return angular.isDefined(this.map);
}
createMarkerLabelStyle(settings) {
return {
width: "200px",
textAlign: "center",
color: settings.labelColor,
background: "none",
border: "none",
fontSize: "12px",
fontFamily: "\"Helvetica Neue\", Arial, Helvetica, sans-serif",
fontWeight: "bold"
};
}
/* eslint-disable no-undef,no-unused-vars*/
updateMarkerLabel(marker, settings) {
if (marker.label) {
marker.label.setContent(settings.labelText);
marker.label.setStyle(this.createMarkerLabelStyle(settings));
}
}
/* eslint-enable no-undef,no-unused-vars */
/* eslint-disable no-undef,no-unused-vars */
updateMarkerColor(marker, color) {
this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
marker.setIcon(iconInfo.icon);
});
}
/* eslint-enable no-undef,,no-unused-vars */
/* eslint-disable no-undef */
updateMarkerIcon(marker, settings) {
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (marker.label) {
marker.label.setOffset(new qq.maps.Size(-100, -iconInfo.size[1]-20));
}
});
}
/* eslint-disable no-undef */
/* eslint-disable no-undef */
createMarkerIcon(marker, settings, onMarkerIconReady) {
var currentImage = settings.currentImage;
var tMap = this;
if (currentImage && currentImage.url) {
this.utils.loadImageAspect(currentImage.url).then(
(aspect) => {
if (aspect) {
var width;
var height;
if (aspect > 1) {
width = currentImage.size;
height = currentImage.size / aspect;
} else {
width = currentImage.size * aspect;
height = currentImage.size;
}
var icon = new qq.maps.MarkerImage(currentImage.url,
new qq.maps.Size(width, height),
new qq.maps.Point(0,0),
new qq.maps.Point(width/2, height),
new qq.maps.Size(width, height));
var iconInfo = {
size: [width, height],
icon: icon
};
onMarkerIconReady(iconInfo);
} else {
tMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
);
} else {
this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
var pinColor = color.substr(1);
var icon = new qq.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=%E2%80%A2|" + pinColor,
new qq.maps.Size(40, 37),
new qq.maps.Point(0,0),
new qq.maps.Point(10, 37));
var iconInfo = {
size: [40, 37],
icon: icon
};
onMarkerIconReady(iconInfo);
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
var marker = new qq.maps.Marker({
position: location
});
var tMap = this;
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
marker.setMap(tMap.map);
if (settings.showLabel) {
marker.label = new qq.maps.Label({
clickable: false,
content: settings.labelText,
offset: new qq.maps.Size(-100, -iconInfo.size[1]-20),
style: tMap.createMarkerLabelStyle(settings),
visible: true,
position: location,
map: tMap.map,
zIndex: 1000
});
}
});
if (settings.displayTooltip) {
this.createTooltip(marker, dsIndex, settings, markerArgs);
}
if (onClickListener) {
qq.maps.event.addListener(marker, 'click', onClickListener);
}
return marker;
}
/* eslint-disable no-undef */
removeMarker(marker) {
marker.setMap(null);
if (marker.label) {
marker.label.setMap(null);
}
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createTooltip(marker, dsIndex, settings, markerArgs) {
var popup = new qq.maps.InfoWindow({
map :this.map
});
var map = this;
qq.maps.event.addListener(marker, 'click', function() {
if (settings.autocloseTooltip) {
map.tooltips.forEach((tooltip) => {
tooltip.popup.close();
});
}
popup.open();
popup.setPosition(marker);
});
this.tooltips.push( {
markerArgs: markerArgs,
popup: popup,
locationSettings: settings,
dsIndex: dsIndex
});
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
updatePolylineColor(polyline, settings, color) {
var options = {
path: polyline.getPath(),
strokeColor: color,
strokeOpacity: settings.strokeOpacity,
strokeWeight: settings.strokeWeight,
map: this.map
};
polyline.setOptions(options);
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createPolyline(locations, settings) {
var polyline = new qq.maps.Polyline({
path: locations,
strokeColor: settings.color,
strokeOpacity: settings.strokeOpacity,
strokeWeight: settings.strokeWeight,
map: this.map
});
return polyline;
}
/* eslint-enable no-undef */
removePolyline(polyline) {
polyline.setMap(null);
}
/* eslint-disable no-undef ,no-unused-vars*/
fitBounds(bounds) {
if (this.dontFitMapBounds && this.defaultZoomLevel) {
this.map.setZoom(this.defaultZoomLevel);
this.map.setCenter(bounds.getCenter());
} else {
var tbMap = this;
qq.maps.event.addListenerOnce(this.map, 'bounds_changed', function() { // eslint-disable-line no-undef
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
tbMap.map.setZoom(tbMap.minZoomLevel);
}
});
this.map.fitBounds(bounds);
}
}
/* eslint-enable no-undef,no-unused-vars */
createLatLng(lat, lng) {
return new qq.maps.LatLng(lat, lng); // eslint-disable-line no-undef
}
extendBoundsWithMarker(bounds, marker) {
bounds.extend(marker.getPosition());
}
getMarkerPosition(marker) {
return marker.getPosition();
}
setMarkerPosition(marker, latLng) {
marker.setPosition(latLng);
if (marker.label) {
marker.label.setPosition(latLng);
}
}
getPolylineLatLngs(polyline) {
return polyline.getPath().getArray();
}
setPolylineLatLngs(polyline, latLngs) {
polyline.setPath(latLngs);
}
createBounds() {
return new qq.maps.LatLngBounds(); // eslint-disable-line no-undef
}
extendBounds(bounds, polyline) {
if (polyline && polyline.getPath()) {
var locations = polyline.getPath();
for (var i = 0; i < locations.getLength(); i++) {
bounds.extend(locations.getAt(i));
}
}
}
invalidateSize() {
qq.maps.event.trigger(this.map, "resize"); // eslint-disable-line no-undef
}
getTooltips() {
return this.tooltips;
}
constructor($containerElement, utils, initCallback, defaultZoomLevel, dontFitMapBounds, minZoomLevel, tmApiKey, tmDefaultMapType) {
var tbMap = this;
this.utils = utils;
this.defaultZoomLevel = defaultZoomLevel;
this.dontFitMapBounds = dontFitMapBounds;
this.minZoomLevel = minZoomLevel;
this.tooltips = [];
this.defaultMapType = tmDefaultMapType;
function clearGlobalId() {
if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
tmGlobals.loadingTmId = null;
}
}
function displayError(message) {
$containerElement.html( // eslint-disable-line angular/angularelement
"<div class='error'>" + message + "</div>"
);
}
function initTencentMap() {
tbMap.map = new qq.maps.Map($containerElement[0], { // eslint-disable-line no-undef
scrollwheel: true,
mapTypeId: getTencentMapTypeId(tbMap.defaultMapType),
zoom: tbMap.defaultZoomLevel || 8
});
if (initCallback) {
initCallback();
}
}
/* eslint-disable no-undef */
function getTencentMapTypeId(mapType) {
var mapTypeId = qq.maps.MapTypeId.ROADMAP;
if (mapType) {
if (mapType === 'hybrid') {
mapTypeId = qq.maps.MapTypeId.HYBRID;
} else if (mapType === 'satellite') {
mapTypeId = qq.maps.MapTypeId.SATELLITE;
} else if (mapType === 'terrain') {
mapTypeId = qq.maps.MapTypeId.ROADMAP;
}
}
return mapTypeId;
}
/* eslint-enable no-undef */
this.mapId = '' + Math.random().toString(36).substr(2, 9);
this.apiKey = tmApiKey || '84d6d83e0e51e481e50454ccbe8986b';
window.tm_authFailure = function () { // eslint-disable-line no-undef, angular/window-service
if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
tmGlobals.loadingTmId = null;
tmGlobals.tmApiKeys[tbMap.apiKey].error = 'Unable to authentificate for tencent Map API.</br>Please check your API key.';
displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
}
};
this.initMapFunctionName = 'initTencentMap_' + this.mapId;
window[this.initMapFunctionName] = function () { // eslint-disable-line no-undef, angular/window-service
tmGlobals.tmApiKeys[tbMap.apiKey].loaded = true;
initTencentMap();
for (var p = 0; p < tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits.length; p++) {
var pendingInit = tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits[p];
pendingInit();
}
tmGlobals.tmApiKeys[tbMap.apiKey].pendingInits = [];
};
if (this.apiKey && this.apiKey.length > 0) {
if (tmGlobals.tmApiKeys[this.apiKey]) {
if (tmGlobals.tmApiKeys[this.apiKey].error) {
displayError(tmGlobals.tmApiKeys[this.apiKey].error);
} else if (tmGlobals.tmApiKeys[this.apiKey].loaded) {
initTencentMap();
} else {
tmGlobals.tmApiKeys[this.apiKey].pendingInits.push(initTencentMap);
}
} else {
tmGlobals.tmApiKeys[this.apiKey] = {
loaded: false,
pendingInits: []
};
var tencentMapScriptRes = 'https://map.qq.com/api/js?v=2.exp&key=' + this.apiKey + '&callback=' + this.initMapFunctionName;
tmGlobals.loadingTmId = this.mapId;
lazyLoad.load({type: 'js', path: tencentMapScriptRes}).then( // eslint-disable-line no-undef
function success() {
setTimeout(clearGlobalId, 2000); // eslint-disable-line no-undef, angular/timeout-service
},
function fail(e) {
clearGlobalId();
tmGlobals.tmApiKeys[tbMap.apiKey].error = 'tencent map api load failed!</br>' + e;
displayError(tmGlobals.tmApiKeys[tbMap.apiKey].error);
}
);
}
} else {
displayError('No tencent Map Api Key provided!');
}
}
inited() {
return angular.isDefined(this.map);
}
createMarkerLabelStyle(settings) {
return {
width: "200px",
textAlign: "center",
color: settings.labelColor,
background: "none",
border: "none",
fontSize: "12px",
fontFamily: "\"Helvetica Neue\", Arial, Helvetica, sans-serif",
fontWeight: "bold"
};
}
/* eslint-disable no-undef,no-unused-vars*/
updateMarkerLabel(marker, settings) {
if (marker.label) {
marker.label.setContent(settings.labelText);
marker.label.setStyle(this.createMarkerLabelStyle(settings));
}
}
/* eslint-enable no-undef,no-unused-vars */
/* eslint-disable no-undef,no-unused-vars */
updateMarkerColor(marker, color) {
this.createDefaultMarkerIcon(marker, color, (iconInfo) => {
marker.setIcon(iconInfo.icon);
});
}
/* eslint-enable no-undef,,no-unused-vars */
/* eslint-disable no-undef */
updateMarkerIcon(marker, settings) {
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
if (marker.label) {
marker.label.setOffset(new qq.maps.Size(-100, -iconInfo.size[1] - 20));
}
});
}
/* eslint-disable no-undef */
/* eslint-disable no-undef */
createMarkerIcon(marker, settings, onMarkerIconReady) {
var currentImage = settings.currentImage;
var tMap = this;
if (currentImage && currentImage.url) {
this.utils.loadImageAspect(currentImage.url).then(
(aspect) => {
if (aspect) {
var width;
var height;
if (aspect > 1) {
width = currentImage.size;
height = currentImage.size / aspect;
} else {
width = currentImage.size * aspect;
height = currentImage.size;
}
var icon = new qq.maps.MarkerImage(currentImage.url,
new qq.maps.Size(width, height),
new qq.maps.Point(0, 0),
new qq.maps.Point(width / 2, height),
new qq.maps.Size(width, height));
var iconInfo = {
size: [width, height],
icon: icon
};
onMarkerIconReady(iconInfo);
} else {
tMap.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
);
} else {
this.createDefaultMarkerIcon(marker, settings.color, onMarkerIconReady);
}
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createDefaultMarkerIcon(marker, color, onMarkerIconReady) {
var pinColor = color.substr(1);
var icon = new qq.maps.MarkerImage("https://chart.apis.google.com/chart?chst=d_map_pin_letter_withshadow&chld=%E2%80%A2|" + pinColor,
new qq.maps.Size(40, 37),
new qq.maps.Point(0, 0),
new qq.maps.Point(10, 37));
var iconInfo = {
size: [40, 37],
icon: icon
};
onMarkerIconReady(iconInfo);
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
var marker = new qq.maps.Marker({
position: location
});
var tMap = this;
this.createMarkerIcon(marker, settings, (iconInfo) => {
marker.setIcon(iconInfo.icon);
marker.setMap(tMap.map);
if (settings.showLabel) {
marker.label = new qq.maps.Label({
clickable: false,
content: settings.labelText,
offset: new qq.maps.Size(-100, -iconInfo.size[1] - 20),
style: tMap.createMarkerLabelStyle(settings),
visible: true,
position: location,
map: tMap.map,
zIndex: 1000
});
}
});
if (settings.displayTooltip) {
this.createTooltip(marker, dsIndex, settings, markerArgs);
}
if (onClickListener) {
qq.maps.event.addListener(marker, 'click', onClickListener);
}
return marker;
}
/* eslint-disable no-undef */
removeMarker(marker) {
marker.setMap(null);
if (marker.label) {
marker.label.setMap(null);
}
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createTooltip(marker, dsIndex, settings, markerArgs) {
var popup = new qq.maps.InfoWindow({
map: this.map
});
var map = this;
qq.maps.event.addListener(marker, 'click', function () {
if (settings.autocloseTooltip) {
map.tooltips.forEach((tooltip) => {
tooltip.popup.close();
});
}
popup.open();
popup.setPosition(marker);
});
this.tooltips.push({
markerArgs: markerArgs,
popup: popup,
locationSettings: settings,
dsIndex: dsIndex
});
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
updatePolylineColor(polyline, settings, color) {
var options = {
path: polyline.getPath(),
strokeColor: color,
strokeOpacity: settings.strokeOpacity,
strokeWeight: settings.strokeWeight,
map: this.map
};
polyline.setOptions(options);
}
/* eslint-enable no-undef */
/* eslint-disable no-undef */
createPolyline(locations, settings) {
var polyline = new qq.maps.Polyline({
path: locations,
strokeColor: settings.color,
strokeOpacity: settings.strokeOpacity,
strokeWeight: settings.strokeWeight,
map: this.map
});
return polyline;
}
/* eslint-enable no-undef */
removePolyline(polyline) {
polyline.setMap(null);
}
/* eslint-disable no-undef */
createPolygon(latLangs, settings) {
let polygon = new qq.maps.Polygon({
map: this.map,
path: latLangs,
strokeColor: settings.polygonStrokeColor,
fillColor: settings.polygonColor,
strokeWeight: settings.polygonStrokeWeight
});
return polygon;
}
/* eslint-disable no-undef */
removePolygon (polygon) {
polygon.setMap(null);
}
/* eslint-disable no-undef,no-unused-vars */
updatePolygonColor (polygon, settings, color) {
let options = {
path: polygon.getPath(),
map: this.map,
strokeColor: color,
fillColor: color,
strokeWeight: settings.polygonStrokeWeight
}
}
/* eslint-disable no-undef ,no-unused-vars*/
getPolygonLatLngs(polygon) {
return polygon.getPath().getArray();
}
setPolygonLatLngs(polygon, latLngs) {
polygon.setPath(latLngs);
}
/* eslint-disable no-undef ,no-unused-vars*/
fitBounds(bounds) {
if (this.dontFitMapBounds && this.defaultZoomLevel) {
this.map.setZoom(this.defaultZoomLevel);
this.map.setCenter(bounds.getCenter());
} else {
var tbMap = this;
qq.maps.event.addListenerOnce(this.map, 'bounds_changed', function () { // eslint-disable-line no-undef
if (!tbMap.defaultZoomLevel && tbMap.map.getZoom() > tbMap.minZoomLevel) {
tbMap.map.setZoom(tbMap.minZoomLevel);
}
});
this.map.fitBounds(bounds);
}
}
/* eslint-enable no-undef,no-unused-vars */
createLatLng(lat, lng) {
return new qq.maps.LatLng(lat, lng); // eslint-disable-line no-undef
}
extendBoundsWithMarker(bounds, marker) {
bounds.extend(marker.getPosition());
}
getMarkerPosition(marker) {
return marker.getPosition();
}
setMarkerPosition(marker, latLng) {
marker.setPosition(latLng);
if (marker.label) {
marker.label.setPosition(latLng);
}
}
getPolylineLatLngs(polyline) {
return polyline.getPath().getArray();
}
setPolylineLatLngs(polyline, latLngs) {
polyline.setPath(latLngs);
}
createBounds() {
return new qq.maps.LatLngBounds(); // eslint-disable-line no-undef
}
extendBounds(bounds, polyline) {
if (polyline && polyline.getPath()) {
var locations = polyline.getPath();
for (var i = 0; i < locations.getLength(); i++) {
bounds.extend(locations.getAt(i));
}
}
}
invalidateSize() {
qq.maps.event.trigger(this.map, "resize"); // eslint-disable-line no-undef
}
getTooltips() {
return this.tooltips;
}
}

Loading…
Cancel
Save