-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Validate utility network topology sample #1689
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things to review. See comments. Mainly, I think the general workflows should be split into smaller functions rather than lengthy connect lambdas and .then lambdas.
bool m_isUpdateVisible; | ||
bool m_validateBtn; | ||
bool m_traceBtn; | ||
bool m_busy; | ||
bool m_clearBtn; | ||
bool m_stateBtn; | ||
int m_attributeValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These all need default values.
Also, I don't understand what m_traceBtn
means as a bool. Same comment for many of these bools.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to m_isTraceBtnEnabled
and similar for others
void setupTraceParameters(); | ||
void connectSignals(); | ||
|
||
Esri::ArcGISRuntime::Map* m_map = nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need all these class members? I would think some of these objects are only needed temporarily, for example do you ever reference m_cred
or many of these in different functions?
I would trim this list as much as reasonably possible. It gives an impression that this workflow is more complicated than necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView); | ||
Esri::ArcGISRuntime::LabelDefinition* createDeviceLabelDefinition(); | ||
Esri::ArcGISRuntime::LabelDefinition* createLineLabelDefinition(); | ||
void getLabelDefinitions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you consider another name for this function? It begins with 'get' but does not return anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to displayLabelDefinitions
signals: | ||
void mapViewChanged(); | ||
void messageChanged(); | ||
void addChoices(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name doesn't match the naming convention for a signal. It should convey a change of some kind, like choicesChanged
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
void isUpdateVisible(); | ||
void updateFieldName(); | ||
void validateBtn(); | ||
void traceBtn(); | ||
void isBusy(); | ||
void clearBtn(); | ||
void stateBtn(); | ||
void attributeValue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review these signals names. They don't follow typical guidelines for events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
|
||
void ValidateUtilityNetworkTopology::onValidate() | ||
{ | ||
m_utilityNetwork = m_mapView->map()->utilityNetworks()->first(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does your logic prevent this from being called before all these are available? If not this will crash. If the service is down, for example, will the user be able to get into this logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added checking
m_deviceFeatureLayer->selectFeaturesAsync(deviceParams, SelectionMode::Add).then(this, [](FeatureQueryResult*) | ||
{ | ||
}); | ||
|
||
m_lineFeatureLayer->selectFeaturesAsync(lineParams, SelectionMode::Add).then(this, [](FeatureQueryResult*) | ||
{ | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense if you don't need to do anything here, but you could clean up unused memory here.
m_deviceFeatureLayer->selectFeaturesAsync(deviceParams, SelectionMode::Add).then(this, [](FeatureQueryResult*) | |
{ | |
}); | |
m_lineFeatureLayer->selectFeaturesAsync(lineParams, SelectionMode::Add).then(this, [](FeatureQueryResult*) | |
{ | |
}); | |
m_deviceFeatureLayer->selectFeaturesAsync(deviceParams, SelectionMode::Add).then(this, [](FeatureQueryResult* rawResult) | |
{ | |
std::unique_ptr<FeatureQueryResult> {rawResult}; | |
}); | |
m_lineFeatureLayer->selectFeaturesAsync(lineParams, SelectionMode::Add).then(this, [](FeatureQueryResult* rawResult) | |
{ | |
std::unique_ptr<FeatureQueryResult> {rawResult}; | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
m_utilityAssetType = m_utilityNetwork | ||
->definition() | ||
->networkSource("Electric Distribution Device") | ||
->assetGroup("Circuit Breaker") | ||
->assetType("Three Phase"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is concise, but if anything goes wrong this will crash. Consider some minimal checking here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
return deviceLabelDefinition; | ||
} | ||
|
||
LabelDefinition* ValidateUtilityNetworkTopology::createLineLabelDefinition() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this function can be const. Everything that can be const, should be const.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
emit isBusy(); | ||
} | ||
|
||
LabelDefinition* ValidateUtilityNetworkTopology::createDeviceLabelDefinition() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be const?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
connect(m_serviceGeodatabase, &ServiceGeodatabase::doneLoading, this, [this, params](const Esri::ArcGISRuntime::Error &loadError) | ||
{ | ||
onServiceGeodatabaseLoaded(params, loadError); | ||
}); | ||
|
||
connect(m_utilityNetwork, &UtilityNetwork::doneLoading, this, [this]() | ||
{ | ||
setupTraceParameters(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the done loading connections should be setup before load is called. Otherwise, it's possible that the load will complete before the signal emits.
ServiceVersionParameters* params = new ServiceVersionParameters(this); | ||
params->setName("ValidateNetworkTopology_" + randomVersionUuid); | ||
params->setAccess(VersionAccess::Private); | ||
params->setDescription("Validate network topology with ArcGIS Runtime"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
params->setDescription("Validate network topology with ArcGIS Runtime"); | |
params->setDescription("Validate network topology with ArcGIS Maps SDK"); |
m_updateFieldName = m_feature->featureTable()->tableName() == "Electric Distribution Device" ? "devicestatus" : "nominalvoltage"; | ||
Field m_field = m_feature->featureTable()->field(m_updateFieldName); | ||
CodedValueDomain m_codedValueDomain = static_cast<CodedValueDomain>(m_field.domain()); | ||
m_codedValues = m_codedValueDomain.codedValues(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
following James's comment, it still feels like more things are member variables than are probably required. In the case of Field, that is now changed to be a local variable, but it still uses the m_
convention, which suggests it's a member when it's really not. We should only make things members if we need to, and if we make them local, they shouldn't use m_
|
||
m_choices.clear(); | ||
|
||
m_choices.append(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need to append an empty string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, to get the attributevalue of the selected feature as the current option in the choices dropdown, first I'm assigning a empty value and replacing it with the feature's attribute value when it's found in the for loop
emit updateFieldName(); | ||
} | ||
|
||
void ValidateUtilityNetworkTopology::onApplyEdits(QString choice) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void ValidateUtilityNetworkTopology::onApplyEdits(QString choice) | |
void ValidateUtilityNetworkTopology::onApplyEdits(const QString& choice) |
if (m_map->loadStatus() != LoadStatus::Loaded) | ||
return; | ||
|
||
Point m_clickPoint = m_mapView->screenToLocation(mouseEvent.position().x(), mouseEvent.position().y()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't seem to be used anywhere. The identify takes the position in directly
|
||
// Get the validation result | ||
UtilityNetworkValidationJob* job = m_utilityNetwork->validateNetworkTopology(m_extent); | ||
job->start(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start should be called after the signal connection is made
UtilityNetworkValidationJob* job = m_utilityNetwork->validateNetworkTopology(m_extent); | ||
job->start(); | ||
|
||
QObject::connect(job, &UtilityNetworkValidationJob::statusChanged, this, [this, job](JobStatus status) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we don't need to specify QObject::
QObject::connect(job, &UtilityNetworkValidationJob::statusChanged, this, [this, job](JobStatus status) | |
connect(job, &UtilityNetworkValidationJob::statusChanged, this, [this, job](JobStatus status) |
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]"); | ||
|
||
TextSymbol* textSymbol = new TextSymbol(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing parents - any time you use new
, you know you'll need to specify a parent object
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]"); | |
TextSymbol* textSymbol = new TextSymbol(); | |
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]", this); | |
TextSymbol* textSymbol = new TextSymbol(this); |
id: updateWindow | ||
visible: model.isUpdateWindowVisible | ||
enabled: visible | ||
anchors.centerIn: parent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typically we put the anchors at the top, right under the id
m_deviceFeatureLayer->clearSelection(); | ||
m_lineFeatureLayer->clearSelection(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to be careful when accessing members without a null check. I tested the branch locally, and got a crash right away. I believe it is because I tried clicking on a feature on the map before the map/utility network were fully loaded, and something was in a null state.
|
||
LabelDefinition* ValidateUtilityNetworkTopology::createDeviceLabelDefinition() const | ||
{ | ||
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]", new QObject()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all of these new QObject()
need to be changed to this
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]", new QObject()); | |
SimpleLabelExpression* labelExpression = new SimpleLabelExpression("[devicestatus]", this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per our offline discussion, removed const
from the methods and parent is changed to this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Description
This PR is to add
Validate utility network topology
sampleType of change
Platforms tested on:
Checklist