我在小部件应用程序中嵌入了一个QML地图。我使用MapQuickItem绘制我在MAP上跟踪的资产的标记。此外,我绘制了前一个跟踪点的历史记录。由于操作员可以添加和删除项目,因此我希望将地图项目和历史记录作为组包含在内,以便我可以轻松删除与资产相关的地图项目。
我是QML的新手,也是JS的新手,所以我通过反复试验来学习。
我想要做的是在折线的每个点上添加一个标记(除了作为实际资产标记的最后一个点)。这些点中的每一个上的标记也是图像(可能是小箭头)。我想根据运动方向旋转此箭头。
所以我有我的Main.qml文件来做地图绘制等。然后我有MapMarker.Qml绘制实际资产的标记。目前图像是硬编码的。然后我有一个AssetTrails.qml文件,目前只是一个Polyline组件。我希望我可以在此路径中添加点标记,因为在删除时删除所有项目都很容易。
有人可能会向我解释如何解决这个问题吗?这可能吗?
我附上我的QML片段以供参考。我意识到这不是很好的代码,但就像我说的那样,我通过反复试验来学习。
Main.qml函数
function addAsset(location, Name)
{
// Load the map marker.
var mapmarkercomp = Qt.createComponent("mapmarker.qml");
assetMarkers.push(mapmarkercomp.createObject(
map, {"coordinate": QtPositioning.coordinate(location.latitude,
location.longitude)}));
if (mapLoadErrorHandler(assetMarkers[assetMarkers.length - 1]))
{
map.center = QtPositioning.coordinate(location.latitude,
location.longitude);
map.zoomLevel = 6;
assetMarkers[assetMarkers.length - 1].name = Name;
assetMarkers[assetMarkers.length - 1].followMe = true;
assetMarkers[assetMarkers.length - 1].transparency = 0;
map.addMapItem(assetMarkers[assetMarkers.length - 1]);
}
}
function addAssetHistory(assetPath, assetName, Colour)
{
// Load the polyline asset trail.
var polylinecomp = Qt.createComponent("mapassettrail.qml");
assetTrails.push(polylinecomp.createObject(map, {"line.color": Colour}));
if (mapLoadErrorHandler(assetTrails[assetTrails.length - 1]))
{
assetTrails[assetTrails.length - 1].path = assetPath;
assetTrails[assetTrails.length - 1].objectName = assetName;
map.addMapItem(assetTrails[assetTrails.length - 1]);
}
}
function removeAssetHistory(assetName)
{
// loop through the assetTrails to find object with the correct asset name and then remove it
var rr;
for (rr in assetTrails)
{
if (assetTrails[rr].objectName === assetName)
{
map.removeMapItem(assetTrails[rr]);
break;
}
}
assetTrails.splice(rr,1);
}
function updateAssetHistory(assetPath, assetName)
{
// find the relevant asset trail for the assetName
var rr;
for (rr in assetTrails)
{
if (assetTrails[rr].objectName === assetName)
{
assetTrails[rr].path = ( assetPath);
}
}
}
MapMarker.qml
import QtQuick 2.5
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtLocation 5.9
import QtPositioning 5.6
import AssetStruct 1.0
MapQuickItem
{
property int spatialPointHeight: 60
id: assetMapItem2
property var name: ""
property var followMe: false
property var transparency: 0.5
anchorPoint.x: assetIcon2.width/2
anchorPoint.y: assetIcon2.height/2
visible: true
sourceItem: Column
{
Image
{
id: assetIcon2
sourceSize.width: spatialPointHeight
sourceSize.height: spatialPointHeight
width: spatialPointHeight
height: spatialPointHeight
// Fade out all icons except for the last one
opacity: 1 - assetMapItem2.transparency
source: "qrc:/chopper.png"
transform: Rotation
{
id: assetRotation2
origin.x: spatialPointHeight/2
origin.y: spatialPointHeight/2
angle: 90
}
}
Text
{
text: name
horizontalAlignment: Text.AlignHCenter
font.bold: true
width: assetIcon2.width + 10
}
}
Component.onCompleted:
{
// map.addMapItem(assetMapItem2);
}
}
AssetTrail.qml
import QtQuick 2.0
import QtQuick 2.5
import QtQuick.Window 2.0
import QtQuick.Controls 1.4
import QtLocation 5.9
import QtPositioning 5.6
import AssetStruct 1.0
MapPolyline
{
id: assetPolylineTrail
line.color: "green"
line.width: 3
}
所以要解释一下我想做多少一点。见下图。跟踪的资产称为Orion1。它目前的位置是Chopper所在的位置。它的旅行历史轨迹是紫色线。在此行中无法看到之前的报告中此图像中有很多,因此我想添加一个"图像"折线上每个点的点/箭头。如果图像是箭头,我可以使用旋转来指示报告的方向。
答案 0 :(得分:2)
根据我的理解,你有一组积分,其中一些必须是awk -v s1=" " -F"[: ]" 'FNR>1{print $1 s1 $1 OFS $2 OFS $3 OFS $4 s1 "0" s1 $5}' OFS=":" Input_file
的一部分,一部分与MapPolyline
一起使用。
可取的是通过模型处理数据,我认为你处理的C ++比MapQuickItem
更多,所以它也是一个不错的选择。在这里,我创建了一个项目,用于存储名称,资产坐标和历史坐标列表。继承自QML
的模型可以添加元素,此模型由管理QAbstractListModel
和MapItemView
的多个MapPolyline
使用。
MapQuickItem
<强>的main.cpp 强>
//assetitem.h
#ifndef ASSETITEM_H
#define ASSETITEM_H
#include <QColor>
#include <QGeoCoordinate>
#include <QString>
class AssetItem{
public:
QString name() const;
void setName(const QString &name);
QGeoCoordinate asset() const;
void setAsset(const QGeoCoordinate &asset);
void appendHistory(const QGeoCoordinate &value);
QList<QGeoCoordinate> getHistory() const;
QColor getColor() const;
void setColor(const QColor &color);
private:
QString mName;
QGeoCoordinate mAsset;
QList<QGeoCoordinate> history;
QColor mColor;
};
#endif // ASSETITEM_H
//assetitem.cpp
#include "assetitem.h"
QString AssetItem::name() const
{
return mName;
}
void AssetItem::setName(const QString &name)
{
mName = name;
}
QGeoCoordinate AssetItem::asset() const
{
return mAsset;
}
void AssetItem::setAsset(const QGeoCoordinate &asset)
{
if(mAsset.isValid())
appendHistory(mAsset);
mAsset = asset;
}
void AssetItem::appendHistory(const QGeoCoordinate &value)
{
history<< value;
}
QList<QGeoCoordinate> AssetItem::getHistory() const{
return history;
}
QColor AssetItem::getColor() const
{
return mColor;
}
void AssetItem::setColor(const QColor &color)
{
mColor = color;
}
//assetlistmodel.h
#ifndef ASSETLISTMODEL_H
#define ASSETLISTMODEL_H
#include "assetitem.h"
#include <QAbstractListModel>
class AssetListModel : public QAbstractListModel
{
Q_OBJECT
public:
using QAbstractListModel::QAbstractListModel;
enum AirportsRoles{
NameRole = Qt::UserRole + 1,
AssetRole,
HistoryRole,
ColorRole
};
Q_INVOKABLE bool addAsset(QGeoCoordinate coord, const QString & name);
bool createAsset(QGeoCoordinate coord, const QString & name);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
private:
QList<AssetItem> mAssets;
};
#endif // ASSETLISTMODEL_H
//assetlistmodel.cpp
#include "assetlistmodel.h"
bool AssetListModel::addAsset(QGeoCoordinate coord, const QString &name)
{
auto it = std::find_if(mAssets.begin(), mAssets.end(), [&](AssetItem const& obj){
return obj.name() == name;
} );
if(it != mAssets.end()){
//append
int row = it - mAssets.begin();
QModelIndex ix = index(row);
return setData(ix, QVariant::fromValue(coord), AssetRole);
}
else{
//create
return createAsset(coord, name);
}
}
bool AssetListModel::createAsset(QGeoCoordinate coord, const QString &name)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
AssetItem it;
it.setName(name);
it.setAsset(coord);
it.setColor(QColor(qrand()%255, qrand()%255, qrand()%255));
mAssets<< it;
endInsertRows();
return true;
}
int AssetListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return mAssets.count();
}
QVariant AssetListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if(index.row() >= 0 && index.row()<rowCount()){
const AssetItem &it = mAssets[index.row()];
if(role==NameRole)
return it.name();
else if (role == AssetRole)
return QVariant::fromValue(it.asset());
else if(role == HistoryRole){
QVariantList history_list;
QList<QGeoCoordinate> coords = it.getHistory();
for(const QGeoCoordinate & coord: coords){
history_list<<QVariant::fromValue(coord);
}
return history_list;
}
else if(role == ColorRole){
return it.getColor();
}
}
return QVariant();
}
QHash<int, QByteArray> AssetListModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[AssetRole]= "asset";
roles[HistoryRole] = "history";
roles[ColorRole] = "color";
return roles;
}
bool AssetListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
return false;
if(index.row() >= 0 && index.row()<rowCount()){
if (role == AssetRole) {
QGeoCoordinate new_asset(value.value<QGeoCoordinate>());
mAssets[index.row()].setAsset(new_asset);
emit dataChanged(index, index, QVector<int>{AssetRole});
return true;
}
}
return false;
}
<强> main.qml 强>
#include "assetlistmodel.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include<QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
AssetListModel model;
QGeoCoordinate coord(41.97732, -87.90801);
model.addAsset(coord, "testing_name1");
model.addAsset(coord, "testing_name2");
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("assetmodel", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
<子> 完整的示例可以在以下link中找到。 子>