There is a number of expressions you can use to convert from layout coordinates to tilemap x,y:
PositionToTileX(x)
PositionToTileY(y)
Convert an X or Y layout co-ordinate in to the corresponding tile number in the tilemap. For example, this can be used to get the tile position under the mouse.
SnapX(x)
SnapY(y)
Snap an X or Y layout co-ordinate to the nearest tile. This also returns a layout co-ordinate, but aligned to the nearest tile in the tilemap.
TileAt(x, y)
Return the tile ID at a position in the tilemap. Note the position is given in tiles, not layout co-ordinates. If the tile at the given position is empty (has been erased), the expression returns -1.
TileToPositionX(x)
TileToPositionY(y)
Convert a tile position to layout co-ordinates. For example, this can be used to position a Sprite object on top of a given tile.
.
So you can get tile number that player is on using this formula:
tilesMap.TileAt(tilesMap.PositionToTileX(player.X), tilesMap.PositionToTileY(player.Y))
You can check 4 points at some offset from the player to prevent it from stepping into water etc.
.
Creating a separate invisible solid tilemap for collision detection is actually a very good and popular solution. It will not make your project file any larger, because you only need one tile (just a black square).
You can auto-generate this collision tilemap based on tiles on your main tilemap. Just loop through all x,y tiles on your main tilemap and set or erase corresponding tiles on the collision tilemap.
When your player is in "walking" mode, erase entire collision tilemap and then set tiles with water, trees, mountains etc. When your player is in "boat" mode, set tiles for the entire collision tilemap, and then erase water tiles.