Create Geo Distance Measure

I am creating a new node of KNIME similar to the ones of Distance Measure but with geographic data, and I have problems at the time of the exit of the node so that it is recognized by the K Nearest Neighbor (Distance Function), and I do not find in the eclipse for KNIME, the package that contains that node, even though it comes out when one is going to compile. Someone could help me?

Regards,

Laura

I think it is in the plugin org.knime.distmatrix?

Steve

Hi Steve
I was able to find the KNIME distance packet, there I saw the code of some of the nodes, because others do not contain a Model where this is the main code, and I saw that a new configuration class was created, which I do not know how I think this node what I want to do, because first I add in the super () this: super (new PortType {BufferedDataTable.TYPE}, new PortType {DistanceMeasurePortObject.TYPE}); and when I compile the node to see the design of the ports of the node I get this: “The node could not be created because the following reason: OutPortType [0] must not be null!”, you know that it is the basic thing that has to contain this type of node to make it work?
regards,
Laura

Hi Laura,

Sorry - this is not something I’ve looked into in any real detail, but a few comments to try:

Firstly, in your NodeModel constructor, you have something like:

public TestNodeModel() {
     super(new PortType[] { BufferedDataTable.TYPE },
			new PortType[] { DistanceMeasurePortObject.TYPE });
}

Which should give you a node with a data table input and a distance measure output port - is that what you wanted? (NB, for future proofing you should use PortTypeRegistry.getInstance().getPortType(DistanceMeasurePortObject.class) instead of the static ‘TYPE’ method)

Now you need to ensure that you implement the correct configure() and execute() methods - in this case you need the methods:

@Override
protected _PortObjectSpec[] configure(PortObjectSpec[] inSpecs) throws InvalidSettingsException {
    return new PortObjectSpec[] { new DistanceMeasurePortSpec() };
}

(NB PortObjectSpec[] as argument and return type) - this is a very simple test implementation which creates an empty port spec, doesnt do any column type checking or anything else - not very interesting!

You also need the correct execute() method - PortObject[] as argument and return type

@Override
protected PortObject[] execute(PortObject[] inObjects, ExecutionContext exec) throws Exception {
    //TODO: Implement!
}

And this is where it gets complicated!

To create a DistanceMeasurePortObject, it would appear that you need a DistanceMeasureConfig, and a DistanceMeasure. You also need to register your new distance measure in the plugin.xml file as an extension (similar to how you add a new node, but the extension point is org.knime.distmatrix,distanceMeasures), for which you also need a DistanceMeasureFactory.

You can get at some of this using the autocomplete in Eclipse, but unfortunately there doesnt appear to be any javadoc or browsable source code. Hopefully someone from KNIME can help with this, as it would be really useful for something I started working on a while back too!

EDIT: There is some documentation here - https://www.knime.com/wiki/distance-measure-developers-guide which may also offer some pointers

Steve

Hi Steve,
I was looking at the development guide for Distance Measure, and there is a part I can not understand, in the Usage in Nodes section, in the execute, they put this: … @Override protected PortObject execute (final PortObject inData, final ExecutionContext exec) throws Exception {end BufferedDataTable in0 = (BufferedDataTable) inData [0]; DistanceMeasure <?> DistanceMeasure = ((DistanceMeasurePortObject) inData [1]). CreateDistanceMeasure (in0.getDataTableSpec (), this);
Now that means the THIS ??, because I do not know what it is referring to, I know it must be a FlowVariableProvider, according to the method createDistanceMeasure. I hope and you can help me with this.
Thank you,
Laura

Hi Laura,

It refers to the calling instance of the NodeModel class (i.e. the class you are currently looking at with the #execute method).

The method signature for DistanceMeasurePortObject#createDistanceMeasure(DataTableSpec, FlowVariableProvider) is not entirely obvious, but if you look at the javadoc for the FlowVariableProvider interface you will see that a NodeModel will suffice here:

Provides access to flow variables. {@link org.knime.core.node.NodeModel} already implements the defined methods and
can therefore easily marked as {@link FlowVariableProvider}.

Hope that clarifies?

Steve

Thanks Steve,
But now I get another error, and I continue to be guided by the documentation, they put in the execute:

final BufferedDataTable in0 = (BufferedDataTable) inData [0]; DistanceMeasure <?> DistanceMeasure = ((DistanceMeasurePortObject) inData [1]). CreateDistanceMeasure (in0.getDataTableSpec (), this);

And when I put it to my form it’s like this:

final BufferedDataTable in0 = (BufferedDataTable) inData [0];
DistanceMeasure <?> DistanceMeasure = ((DistanceMeasurePortObject) inData [0]). CreateDistanceMeasure (in0.getDataTableSpec (), (FlowVariableProvider) GeodistanceNodeModel.this);

And I get this error:

Execute failed: org.knime.core.node.BufferedDataTable can not be cast to org.knime.distance.DistanceMeasurePortObject

What I can do???

Their example looks like it is expecting the node to have 2 input ports:

  1. A BufferedDataTable - as indicated by:

    final BufferedDataTable in0 = (BufferedDataTable) inData [0];

  2. A DistanceMeasurePortObject - as indicated by:

    DistanceMeasure <?> DistanceMeasure =((DistanceMeasurePortObject) inData [1]). CreateDistanceMeasure (in0.getDataTableSpec (), this);

In your case, you are trying to treat the 1st input port as both port types (final BufferedDataTable in0 = (BufferedDataTable) inData [0]; and (DistanceMeasurePortObject) inData [0])) - so it may just be that you have an error in the array index for the second of those (i.e. [0] in place of [1])?

Steve

Hi Steve
I created the node and I think it works, at least it runs, I tried to do it for the documentation but it does not work for me, what is there does not work for me, they give me a lot of errors, so let me be guided by the implementations of other nodes similar, but everyone has many different things. For now what I do not understand is how to make that when I connect my node to another node (for example the K nearest neighbord (Distance Function)) this recognizes me the column that I am selecting in my node, because this is what I get:
error
How do I achieve recognition?
Regards,
Laura

I solved the problem, if someone has the same doubt, then write and I answer

1 Like

Well done Laura - sorry I didnt get another chance to look at this.

Steve

1 Like